extends: extends:
- '@gitlab' - '@gitlab'
- plugin:promise/recommended - plugin:promise/recommended
- plugin:no-jquery/slim
globals: globals:
__webpack_public_path__: true __webpack_public_path__: true
gl: false gl: false
...@@ -44,10 +45,9 @@ rules: ...@@ -44,10 +45,9 @@ rules:
vue/no-use-v-if-with-v-for: off vue/no-use-v-if-with-v-for: off
vue/no-v-html: off vue/no-v-html: off
vue/use-v-on-exact: off vue/use-v-on-exact: off
no-jquery/no-ajax: error no-jquery/no-animate: off
no-jquery/no-ajax-events: error no-jquery/no-animate-toggle: off
no-jquery/no-load: error no-jquery/no-fade: off
no-jquery/no-load-shorthand: error
no-jquery/no-serialize: error no-jquery/no-serialize: error
promise/always-return: off promise/always-return: off
promise/no-callback-in-promise: off promise/no-callback-in-promise: off
... ...
......
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
## 12.5.5
- No changes.
## 12.5.4 ## 12.5.4
### Security (1 change) ### Security (1 change)
... ...
......
...@@ -4,7 +4,15 @@ entry. ...@@ -4,7 +4,15 @@ entry.
   
## 12.5.5 ## 12.5.5
   
- No changes. ### Security (1 change)
- Upgrade Akismet gem to v3.0.0. !21786
### Fixed (2 changes)
- Fix error in updating runner session. !20902
- Fix Asana integration. !21501
   
## 12.5.4 ## 12.5.4
   
... ...
......
...@@ -222,6 +222,7 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -222,6 +222,7 @@ document.addEventListener('DOMContentLoaded', () => {
} }
}); });
// eslint-disable-next-line no-jquery/no-ajax-events
$(document).ajaxError((e, xhrObj) => { $(document).ajaxError((e, xhrObj) => {
const ref = xhrObj.status; const ref = xhrObj.status;
... ...
......
/* eslint-disable no-restricted-properties, no-var, camelcase, /* eslint-disable no-restricted-properties, camelcase,
no-unused-expressions, one-var, default-case, no-unused-expressions, default-case,
consistent-return, no-alert, no-param-reassign, no-else-return, consistent-return, no-alert, no-param-reassign, no-else-return,
vars-on-top, no-shadow, no-useless-escape, no-shadow, no-useless-escape,
class-methods-use-this */ class-methods-use-this */
/* global ResolveService */ /* global ResolveService */
...@@ -224,18 +224,18 @@ export default class Notes { ...@@ -224,18 +224,18 @@ export default class Notes {
} }
keydownNoteText(e) { keydownNoteText(e) {
var $textarea, let discussionNoteForm;
discussionNoteForm, let editNote;
editNote, let myLastNote;
myLastNote, let myLastNoteEditBtn;
myLastNoteEditBtn, let newText;
newText, let originalText;
originalText;
if (isMetaKey(e)) { if (isMetaKey(e)) {
return; return;
} }
$textarea = $(e.target); const $textarea = $(e.target);
// Edit previous note when UP arrow is hit // Edit previous note when UP arrow is hit
switch (e.which) { switch (e.which) {
case 38: case 38:
...@@ -325,11 +325,10 @@ export default class Notes { ...@@ -325,11 +325,10 @@ export default class Notes {
* if there aren't new notes coming from the server * if there aren't new notes coming from the server
*/ */
setPollingInterval(shouldReset) { setPollingInterval(shouldReset) {
var nthInterval;
if (shouldReset == null) { if (shouldReset == null) {
shouldReset = true; shouldReset = true;
} }
nthInterval = this.basePollingInterval * Math.pow(2, this.maxPollingSteps - 1); const nthInterval = this.basePollingInterval * Math.pow(2, this.maxPollingSteps - 1);
if (shouldReset) { if (shouldReset) {
this.pollingInterval = this.basePollingInterval; this.pollingInterval = this.basePollingInterval;
} else if (this.pollingInterval < nthInterval) { } else if (this.pollingInterval < nthInterval) {
...@@ -339,7 +338,7 @@ export default class Notes { ...@@ -339,7 +338,7 @@ export default class Notes {
} }
handleQuickActions(noteEntity) { handleQuickActions(noteEntity) {
var votesBlock; let votesBlock;
if (noteEntity.commands_changes) { if (noteEntity.commands_changes) {
if ('merge' in noteEntity.commands_changes) { if ('merge' in noteEntity.commands_changes) {
Notes.checkMergeRequestStatus(); Notes.checkMergeRequestStatus();
...@@ -462,14 +461,16 @@ export default class Notes { ...@@ -462,14 +461,16 @@ export default class Notes {
* Render note in discussion area. To render inline notes use renderDiscussionNote. * Render note in discussion area. To render inline notes use renderDiscussionNote.
*/ */
renderDiscussionNote(noteEntity, $form) { renderDiscussionNote(noteEntity, $form) {
var discussionContainer, form, row, lineType, diffAvatarContainer; let discussionContainer;
let row;
if (!Notes.isNewNote(noteEntity, this.note_ids)) { if (!Notes.isNewNote(noteEntity, this.note_ids)) {
return; return;
} }
this.note_ids.push(noteEntity.id); this.note_ids.push(noteEntity.id);
form = $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`); const form =
$form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`);
row = row =
form.length || !noteEntity.discussion_line_code form.length || !noteEntity.discussion_line_code
? form.closest('tr') ? form.closest('tr')
...@@ -479,8 +480,8 @@ export default class Notes { ...@@ -479,8 +480,8 @@ export default class Notes {
row = form; row = form;
} }
lineType = this.isParallelView() ? form.find('#line_type').val() : 'old'; const lineType = this.isParallelView() ? form.find('#line_type').val() : 'old';
diffAvatarContainer = row const diffAvatarContainer = row
.prevAll('.line_holder') .prevAll('.line_holder')
.first() .first()
.find(`.js-avatar-container.${lineType}_line`); .find(`.js-avatar-container.${lineType}_line`);
...@@ -491,15 +492,17 @@ export default class Notes { ...@@ -491,15 +492,17 @@ export default class Notes {
} }
if (discussionContainer.length === 0) { if (discussionContainer.length === 0) {
if (noteEntity.diff_discussion_html) { if (noteEntity.diff_discussion_html) {
var $discussion = $(noteEntity.diff_discussion_html).renderGFM(); const $discussion = $(noteEntity.diff_discussion_html).renderGFM();
if (!this.isParallelView() || row.hasClass('js-temp-notes-holder') || noteEntity.on_image) { if (!this.isParallelView() || row.hasClass('js-temp-notes-holder') || noteEntity.on_image) {
// insert the note and the reply button after the temp row // insert the note and the reply button after the temp row
row.after($discussion); row.after($discussion);
} else { } else {
// Merge new discussion HTML in // Merge new discussion HTML in
var $notes = $discussion.find(`.notes[data-discussion-id="${noteEntity.discussion_id}"]`); const $notes = $discussion.find(
var contentContainerClass = $notes `.notes[data-discussion-id="${noteEntity.discussion_id}"]`,
);
const contentContainerClass = $notes
.closest('.notes-content') .closest('.notes-content')
.attr('class') .attr('class')
.split(' ') .split(' ')
...@@ -537,7 +540,7 @@ export default class Notes { ...@@ -537,7 +540,7 @@ export default class Notes {
} }
renderDiscussionAvatar(diffAvatarContainer, noteEntity) { renderDiscussionAvatar(diffAvatarContainer, noteEntity) {
var avatarHolder = diffAvatarContainer.find('.diff-comment-avatar-holders'); let avatarHolder = diffAvatarContainer.find('.diff-comment-avatar-holders');
if (!avatarHolder.length) { if (!avatarHolder.length) {
avatarHolder = document.createElement('diff-note-avatars'); avatarHolder = document.createElement('diff-note-avatars');
...@@ -557,8 +560,7 @@ export default class Notes { ...@@ -557,8 +560,7 @@ export default class Notes {
* Resets buttons. * Resets buttons.
*/ */
resetMainTargetForm(e) { resetMainTargetForm(e) {
var form; const form = $('.js-main-target-form');
form = $('.js-main-target-form');
// remove validation errors // remove validation errors
form.find('.js-errors').remove(); form.find('.js-errors').remove();
// reset text and preview // reset text and preview
...@@ -572,7 +574,7 @@ export default class Notes { ...@@ -572,7 +574,7 @@ export default class Notes {
.data('autosave') .data('autosave')
.reset(); .reset();
var event = document.createEvent('Event'); const event = document.createEvent('Event');
event.initEvent('autosize:update', true, false); event.initEvent('autosize:update', true, false);
form.find('.js-autosize')[0].dispatchEvent(event); form.find('.js-autosize')[0].dispatchEvent(event);
...@@ -580,8 +582,7 @@ export default class Notes { ...@@ -580,8 +582,7 @@ export default class Notes {
} }
reenableTargetFormSubmitButton() { reenableTargetFormSubmitButton() {
var form; const form = $('.js-main-target-form');
form = $('.js-main-target-form');
return form.find('.js-note-text').trigger('input'); return form.find('.js-note-text').trigger('input');
} }
...@@ -591,9 +592,8 @@ export default class Notes { ...@@ -591,9 +592,8 @@ export default class Notes {
* Sets some hidden fields in the form. * Sets some hidden fields in the form.
*/ */
setupMainTargetNoteForm(enableGFM) { setupMainTargetNoteForm(enableGFM) {
var form;
// find the form // find the form
form = $('.js-new-note-form'); const form = $('.js-new-note-form');
// Set a global clone of the form for later cloning // Set a global clone of the form for later cloning
this.formClone = form.clone(); this.formClone = form.clone();
// show the form // show the form
...@@ -626,10 +626,9 @@ export default class Notes { ...@@ -626,10 +626,9 @@ export default class Notes {
* show the form * show the form
*/ */
setupNoteForm(form, enableGFM = defaultAutocompleteConfig) { setupNoteForm(form, enableGFM = defaultAutocompleteConfig) {
var textarea, key;
this.glForm = new GLForm(form, enableGFM); this.glForm = new GLForm(form, enableGFM);
textarea = form.find('.js-note-text'); const textarea = form.find('.js-note-text');
key = [ const key = [
s__('NoteForm|Note'), s__('NoteForm|Note'),
form.find('#note_noteable_type').val(), form.find('#note_noteable_type').val(),
form.find('#note_noteable_id').val(), form.find('#note_noteable_id').val(),
...@@ -686,8 +685,8 @@ export default class Notes { ...@@ -686,8 +685,8 @@ export default class Notes {
*/ */
addDiscussionNote($form, note, isNewDiffComment) { addDiscussionNote($form, note, isNewDiffComment) {
if ($form.attr('data-resolve-all') != null) { if ($form.attr('data-resolve-all') != null) {
var discussionId = $form.data('discussionId'); const discussionId = $form.data('discussionId');
var mergeRequestId = $form.data('noteableIid'); const mergeRequestId = $form.data('noteableIid');
if (ResolveService != null) { if (ResolveService != null) {
ResolveService.toggleResolveForDiscussion(mergeRequestId, discussionId); ResolveService.toggleResolveForDiscussion(mergeRequestId, discussionId);
...@@ -707,13 +706,12 @@ export default class Notes { ...@@ -707,13 +706,12 @@ export default class Notes {
* Updates the current note field. * Updates the current note field.
*/ */
updateNote(noteEntity, $targetNote) { updateNote(noteEntity, $targetNote) {
var $noteEntityEl, $note_li;
// Convert returned HTML to a jQuery object so we can modify it further // Convert returned HTML to a jQuery object so we can modify it further
$noteEntityEl = $(noteEntity.html); const $noteEntityEl = $(noteEntity.html);
this.revertNoteEditForm($targetNote); this.revertNoteEditForm($targetNote);
$noteEntityEl.renderGFM(); $noteEntityEl.renderGFM();
// Find the note's `li` element by ID and replace it with the updated HTML // Find the note's `li` element by ID and replace it with the updated HTML
$note_li = $(`.note-row-${noteEntity.id}`); const $note_li = $(`.note-row-${noteEntity.id}`);
$note_li.replaceWith($noteEntityEl); $note_li.replaceWith($noteEntityEl);
this.setupNewNote($noteEntityEl); this.setupNewNote($noteEntityEl);
...@@ -724,17 +722,17 @@ export default class Notes { ...@@ -724,17 +722,17 @@ export default class Notes {
} }
checkContentToAllowEditing($el) { checkContentToAllowEditing($el) {
var initialContent = $el const initialContent = $el
.find('.original-note-content') .find('.original-note-content')
.text() .text()
.trim(); .trim();
var currentContent = $el.find('.js-note-text').val(); const currentContent = $el.find('.js-note-text').val();
var isAllowed = true; let isAllowed = true;
if (currentContent === initialContent) { if (currentContent === initialContent) {
this.removeNoteEditForm($el); this.removeNoteEditForm($el);
} else { } else {
var isWidgetVisible = isInViewport($el.get(0)); const isWidgetVisible = isInViewport($el.get(0));
if (!isWidgetVisible) { if (!isWidgetVisible) {
scrollToElement($el); scrollToElement($el);
...@@ -756,13 +754,13 @@ export default class Notes { ...@@ -756,13 +754,13 @@ export default class Notes {
showEditForm(e) { showEditForm(e) {
e.preventDefault(); e.preventDefault();
var $target = $(e.target); const $target = $(e.target);
var $editForm = $(this.getEditFormSelector($target)); const $editForm = $(this.getEditFormSelector($target));
var $note = $target.closest('.note'); const $note = $target.closest('.note');
var $currentlyEditing = $('.note.is-editing:visible'); const $currentlyEditing = $('.note.is-editing:visible');
if ($currentlyEditing.length) { if ($currentlyEditing.length) {
var isEditAllowed = this.checkContentToAllowEditing($currentlyEditing); const isEditAllowed = this.checkContentToAllowEditing($currentlyEditing);
if (!isEditAllowed) { if (!isEditAllowed) {
return; return;
...@@ -802,8 +800,8 @@ export default class Notes { ...@@ -802,8 +800,8 @@ export default class Notes {
revertNoteEditForm($target) { revertNoteEditForm($target) {
$target = $target || $('.note.is-editing:visible'); $target = $target || $('.note.is-editing:visible');
var selector = this.getEditFormSelector($target); const selector = this.getEditFormSelector($target);
var $editForm = $(selector); const $editForm = $(selector);
$editForm.insertBefore('.diffs'); $editForm.insertBefore('.diffs');
$editForm.find('.js-comment-save-button').enable(); $editForm.find('.js-comment-save-button').enable();
...@@ -811,7 +809,7 @@ export default class Notes { ...@@ -811,7 +809,7 @@ export default class Notes {
} }
getEditFormSelector($el) { getEditFormSelector($el) {
var selector = '.note-edit-form:not(.mr-note-edit-form)'; let selector = '.note-edit-form:not(.mr-note-edit-form)';
if ($el.parents('#diffs').length) { if ($el.parents('#diffs').length) {
selector = '.note-edit-form.mr-note-edit-form'; selector = '.note-edit-form.mr-note-edit-form';
...@@ -821,7 +819,7 @@ export default class Notes { ...@@ -821,7 +819,7 @@ export default class Notes {
} }
removeNoteEditForm($note) { removeNoteEditForm($note) {
var form = $note.find('.diffs .current-note-edit-form'); const form = $note.find('.diffs .current-note-edit-form');
$note.removeClass('is-editing'); $note.removeClass('is-editing');
form.removeClass('current-note-edit-form'); form.removeClass('current-note-edit-form');
...@@ -837,9 +835,8 @@ export default class Notes { ...@@ -837,9 +835,8 @@ export default class Notes {
* Removes the whole discussion if the last note is being removed. * Removes the whole discussion if the last note is being removed.
*/ */
removeNote(e) { removeNote(e) {
var noteElId, $note; const $note = $(e.currentTarget).closest('.note');
$note = $(e.currentTarget).closest('.note'); const noteElId = $note.attr('id');
noteElId = $note.attr('id');
$(`.note[id="${noteElId}"]`).each((i, el) => { $(`.note[id="${noteElId}"]`).each((i, el) => {
// A same note appears in the "Discussion" and in the "Changes" tab, we have // A same note appears in the "Discussion" and in the "Changes" tab, we have
// to remove all. Using $('.note[id='noteId']') ensure we get all the notes, // to remove all. Using $('.note[id='noteId']') ensure we get all the notes,
...@@ -915,9 +912,8 @@ export default class Notes { ...@@ -915,9 +912,8 @@ export default class Notes {
} }
replyToDiscussionNote(target) { replyToDiscussionNote(target) {
var form, replyLink; const form = this.cleanForm(this.formClone.clone());
form = this.cleanForm(this.formClone.clone()); const replyLink = $(target).closest('.js-discussion-reply-button');
replyLink = $(target).closest('.js-discussion-reply-button');
// insert the form after the button // insert the form after the button
replyLink replyLink
.closest('.discussion-reply-holder') .closest('.discussion-reply-holder')
...@@ -942,7 +938,7 @@ export default class Notes { ...@@ -942,7 +938,7 @@ export default class Notes {
diffFileData = dataHolder.closest('.image'); diffFileData = dataHolder.closest('.image');
} }
var discussionID = dataHolder.data('discussionId'); const discussionID = dataHolder.data('discussionId');
if (discussionID) { if (discussionID) {
form.attr('data-discussion-id', discussionID); form.attr('data-discussion-id', discussionID);
...@@ -985,7 +981,7 @@ export default class Notes { ...@@ -985,7 +981,7 @@ export default class Notes {
form.removeClass('js-main-target-form').addClass('discussion-form js-discussion-note-form'); form.removeClass('js-main-target-form').addClass('discussion-form js-discussion-note-form');
if (typeof gl.diffNotesCompileComponents !== 'undefined') { if (typeof gl.diffNotesCompileComponents !== 'undefined') {
var $commentBtn = form.find('comment-and-resolve-btn'); const $commentBtn = form.find('comment-and-resolve-btn');
$commentBtn.attr(':discussion-id', `'${discussionID}'`); $commentBtn.attr(':discussion-id', `'${discussionID}'`);
gl.diffNotesCompileComponents(); gl.diffNotesCompileComponents();
...@@ -1042,16 +1038,20 @@ export default class Notes { ...@@ -1042,16 +1038,20 @@ export default class Notes {
} }
toggleDiffNote({ target, lineType, forceShow, showReplyInput = false }) { toggleDiffNote({ target, lineType, forceShow, showReplyInput = false }) {
var $link, addForm, hasNotes, newForm, noteForm, replyButton, row, rowCssToAdd; let addForm;
$link = $(target); let newForm;
row = $link.closest('tr'); let noteForm;
let replyButton;
let rowCssToAdd;
const $link = $(target);
const row = $link.closest('tr');
const nextRow = row.next(); const nextRow = row.next();
let targetRow = row; let targetRow = row;
if (nextRow.is('.notes_holder')) { if (nextRow.is('.notes_holder')) {
targetRow = nextRow; targetRow = nextRow;
} }
hasNotes = nextRow.is('.notes_holder'); const hasNotes = nextRow.is('.notes_holder');
addForm = false; addForm = false;
let lineTypeSelector = ''; let lineTypeSelector = '';
rowCssToAdd = rowCssToAdd =
...@@ -1111,9 +1111,8 @@ export default class Notes { ...@@ -1111,9 +1111,8 @@ export default class Notes {
* Removes the form and if necessary it's temporary row. * Removes the form and if necessary it's temporary row.
*/ */
removeDiscussionNoteForm(form) { removeDiscussionNoteForm(form) {
var glForm, row; const row = form.closest('tr');
row = form.closest('tr'); const glForm = form.data('glForm');
glForm = form.data('glForm');
glForm.destroy(); glForm.destroy();
form form
.find('.js-note-text') .find('.js-note-text')
...@@ -1158,10 +1157,9 @@ export default class Notes { ...@@ -1158,10 +1157,9 @@ export default class Notes {
* Updates the file name for the selected attachment. * Updates the file name for the selected attachment.
*/ */
updateFormAttachment() { updateFormAttachment() {
var filename, form; const form = $(this).closest('form');
form = $(this).closest('form');
// get only the basename // get only the basename
filename = $(this) const filename = $(this)
.val() .val()
.replace(/^.*[\\\/]/, ''); .replace(/^.*[\\\/]/, '');
return form.find('.js-attachment-filename').text(filename); return form.find('.js-attachment-filename').text(filename);
...@@ -1175,11 +1173,12 @@ export default class Notes { ...@@ -1175,11 +1173,12 @@ export default class Notes {
} }
updateTargetButtons(e) { updateTargetButtons(e) {
var closebtn, closetext, form, reopenbtn, reopentext, textarea; let closetext;
textarea = $(e.target); let reopentext;
form = textarea.parents('form'); const textarea = $(e.target);
reopenbtn = form.find('.js-note-target-reopen'); const form = textarea.parents('form');
closebtn = form.find('.js-note-target-close'); const reopenbtn = form.find('.js-note-target-reopen');
const closebtn = form.find('.js-note-target-close');
if (textarea.val().trim().length > 0) { if (textarea.val().trim().length > 0) {
reopentext = reopenbtn.attr('data-alternative-text'); reopentext = reopenbtn.attr('data-alternative-text');
...@@ -1215,16 +1214,16 @@ export default class Notes { ...@@ -1215,16 +1214,16 @@ export default class Notes {
} }
putEditFormInPlace($el) { putEditFormInPlace($el) {
var $editForm = $(this.getEditFormSelector($el)); const $editForm = $(this.getEditFormSelector($el));
var $note = $el.closest('.note'); const $note = $el.closest('.note');
$editForm.insertAfter($note.find('.note-text')); $editForm.insertAfter($note.find('.note-text'));
var $originalContentEl = $note.find('.original-note-content'); const $originalContentEl = $note.find('.original-note-content');
var originalContent = $originalContentEl.text().trim(); const originalContent = $originalContentEl.text().trim();
var postUrl = $originalContentEl.data('postUrl'); const postUrl = $originalContentEl.data('postUrl');
var targetId = $originalContentEl.data('targetId'); const targetId = $originalContentEl.data('targetId');
var targetType = $originalContentEl.data('targetType'); const targetType = $originalContentEl.data('targetType');
this.glForm = new GLForm($editForm.find('form'), this.enableGFM); this.glForm = new GLForm($editForm.find('form'), this.enableGFM);
... ...
......
# frozen_string_literal: true
class Projects::Environments::SampleMetricsController < Projects::ApplicationController
def query
result = Metrics::SampleMetricsService.new(params[:identifier]).query
if result
render json: { "status": "success", "data": { "resultType": "matrix", "result": result } }
else
render_404
end
end
end
...@@ -162,7 +162,7 @@ module DiffHelper ...@@ -162,7 +162,7 @@ module DiffHelper
end end
def render_overflow_warning?(diffs_collection) def render_overflow_warning?(diffs_collection)
diff_files = diffs_collection.diff_files diff_files = diffs_collection.raw_diff_files
if diff_files.any?(&:too_large?) if diff_files.any?(&:too_large?)
Gitlab::Metrics.add_event(:diffs_overflow_single_file_limits) Gitlab::Metrics.add_event(:diffs_overflow_single_file_limits)
... ...
......
...@@ -55,10 +55,10 @@ module Clusters ...@@ -55,10 +55,10 @@ module Clusters
) )
end end
def upgrade_command(values) def patch_command(values)
::Gitlab::Kubernetes::Helm::InstallCommand.new( ::Gitlab::Kubernetes::Helm::PatchCommand.new(
name: name, name: name,
version: VERSION, version: version,
rbac: cluster.platform_kubernetes_rbac?, rbac: cluster.platform_kubernetes_rbac?,
chart: chart, chart: chart,
files: files_with_replaced_values(values) files: files_with_replaced_values(values)
... ...
......
...@@ -42,13 +42,13 @@ class DiffsEntity < Grape::Entity ...@@ -42,13 +42,13 @@ class DiffsEntity < Grape::Entity
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
expose :added_lines do |diffs| expose :added_lines do |diffs|
diffs.diff_files.sum(&:added_lines) diffs.raw_diff_files.sum(&:added_lines)
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
expose :removed_lines do |diffs| expose :removed_lines do |diffs|
diffs.diff_files.sum(&:removed_lines) diffs.raw_diff_files.sum(&:removed_lines)
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
... ...
......
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
class DiffsMetadataEntity < DiffsEntity class DiffsMetadataEntity < DiffsEntity
unexpose :diff_files unexpose :diff_files
expose :diff_files, using: DiffFileMetadataEntity expose :raw_diff_files, as: :diff_files, using: DiffFileMetadataEntity
end end
...@@ -61,8 +61,8 @@ module Clusters ...@@ -61,8 +61,8 @@ module Clusters
@update_command ||= app.update_command @update_command ||= app.update_command
end end
def upgrade_command(new_values = "") def patch_command(new_values = "")
app.upgrade_command(new_values) app.patch_command(new_values)
end end
end end
end end
... ...
......
# frozen_string_literal: true
module Metrics
class SampleMetricsService
DIRECTORY = "sample_metrics"
attr_reader :identifier
def initialize(identifier)
@identifier = identifier
end
def query
return unless identifier && File.exist?(file_location)
YAML.load_file(File.expand_path(file_location, __dir__))
end
private
def file_location
sanitized_string = identifier.gsub(/[^0-9A-Za-z_]/, '')
File.join(Rails.root, DIRECTORY, "#{sanitized_string}.yml")
end
end
end
---
title: Add protected branch permission check to run downstream pipelines
merge_request: 20964
author:
type: fixed
---
title: Genereate a set of sample prometheus metrics and route to the sample metrics
when enabled
merge_request: 19987
author:
type: added
--- ---
title: 'When a forked project is less visible than its source, merge requests now target the less visible project by default.' title: 'When a forked project is less visible than its source, merge requests opened in the fork now target the less visible project by default.'
merge_request: 21517 merge_request: 21517
author: author:
type: changed type: changed
---
title: Add indexes on deployments to improve environments search
merge_request: 21789
author:
type: performance
---
title: Fix Asana integration
merge_request: 21501
author:
type: fixed
---
title: Fix error in updating runner session
merge_request: 20902
author:
type: fixed
---
title: Upgrade Akismet gem to v3.0.0
merge_request: 21786
author:
type: security
---
title: Limit max metrics embeds in GFM to 100
merge_request: 21356
author:
type: performance