diff options
28 files changed, 187 insertions, 121 deletions
diff --git a/app/assets/javascripts/gl_form.js b/app/assets/javascripts/gl_form.js index 184c98813f1..9f5eba353d7 100644 --- a/app/assets/javascripts/gl_form.js +++ b/app/assets/javascripts/gl_form.js @@ -2,7 +2,7 @@ import $ from 'jquery'; import autosize from 'autosize'; import GfmAutoComplete from './gfm_auto_complete'; import dropzoneInput from './dropzone_input'; -import textUtils from './lib/utils/text_markdown'; +import { addMarkdownListeners, removeMarkdownListeners } from './lib/utils/text_markdown'; export default class GLForm { constructor(form, enableGFM = false) { @@ -47,7 +47,7 @@ export default class GLForm { } // form and textarea event listeners this.addEventListeners(); - textUtils.init(this.form); + addMarkdownListeners(this.form); // hide discard button this.form.find('.js-note-discard').hide(); this.form.show(); @@ -86,7 +86,7 @@ export default class GLForm { clearEventListeners() { this.textarea.off('focus'); this.textarea.off('blur'); - textUtils.removeListeners(this.form); + removeMarkdownListeners(this.form); } addEventListeners() { diff --git a/app/assets/javascripts/lib/utils/text_markdown.js b/app/assets/javascripts/lib/utils/text_markdown.js index 470e3e5c52e..5a16adea4dc 100644 --- a/app/assets/javascripts/lib/utils/text_markdown.js +++ b/app/assets/javascripts/lib/utils/text_markdown.js @@ -1,28 +1,25 @@ /* eslint-disable import/prefer-default-export, func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, quotes, one-var, one-var-declaration-per-line, operator-assignment, no-else-return, prefer-template, prefer-arrow-callback, no-empty, max-len, consistent-return, no-unused-vars, no-return-assign, max-len, vars-on-top */ - import $ from 'jquery'; +import { insertText } from '~/lib/utils/common_utils'; -const textUtils = {}; - -textUtils.selectedText = function(text, textarea) { +function selectedText(text, textarea) { return text.substring(textarea.selectionStart, textarea.selectionEnd); -}; +} -textUtils.lineBefore = function(text, textarea) { +function lineBefore(text, textarea) { var split; split = text.substring(0, textarea.selectionStart).trim().split('\n'); return split[split.length - 1]; -}; +} -textUtils.lineAfter = function(text, textarea) { +function lineAfter(text, textarea) { return text.substring(textarea.selectionEnd).trim().split('\n')[0]; -}; +} -textUtils.blockTagText = function(text, textArea, blockTag, selected) { - var lineAfter, lineBefore; - lineBefore = this.lineBefore(text, textArea); - lineAfter = this.lineAfter(text, textArea); - if (lineBefore === blockTag && lineAfter === blockTag) { +function blockTagText(text, textArea, blockTag, selected) { + const before = lineBefore(text, textArea); + const after = lineAfter(text, textArea); + if (before === blockTag && after === blockTag) { // To remove the block tag we have to select the line before & after if (blockTag != null) { textArea.selectionStart = textArea.selectionStart - (blockTag.length + 1); @@ -32,10 +29,30 @@ textUtils.blockTagText = function(text, textArea, blockTag, selected) { } else { return blockTag + "\n" + selected + "\n" + blockTag; } -}; +} -textUtils.insertText = function(textArea, text, tag, blockTag, selected, wrap) { - var insertText, inserted, selectedSplit, startChar, removedLastNewLine, removedFirstNewLine, currentLineEmpty, lastNewLine; +function moveCursor(textArea, tag, wrapped, removedLastNewLine) { + var pos; + if (!textArea.setSelectionRange) { + return; + } + if (textArea.selectionStart === textArea.selectionEnd) { + if (wrapped) { + pos = textArea.selectionStart - tag.length; + } else { + pos = textArea.selectionStart; + } + + if (removedLastNewLine) { + pos -= 1; + } + + return textArea.setSelectionRange(pos, pos); + } +} + +export function insertMarkdownText(textArea, text, tag, blockTag, selected, wrap) { + var textToInsert, inserted, selectedSplit, startChar, removedLastNewLine, removedFirstNewLine, currentLineEmpty, lastNewLine; removedLastNewLine = false; removedFirstNewLine = false; currentLineEmpty = false; @@ -67,9 +84,9 @@ textUtils.insertText = function(textArea, text, tag, blockTag, selected, wrap) { if (selectedSplit.length > 1 && (!wrap || (blockTag != null && blockTag !== ''))) { if (blockTag != null && blockTag !== '') { - insertText = this.blockTagText(text, textArea, blockTag, selected); + textToInsert = blockTagText(text, textArea, blockTag, selected); } else { - insertText = selectedSplit.map(function(val) { + textToInsert = selectedSplit.map(function(val) { if (val.indexOf(tag) === 0) { return "" + (val.replace(tag, '')); } else { @@ -78,78 +95,42 @@ textUtils.insertText = function(textArea, text, tag, blockTag, selected, wrap) { }).join('\n'); } } else { - insertText = "" + startChar + tag + selected + (wrap ? tag : ' '); + textToInsert = "" + startChar + tag + selected + (wrap ? tag : ' '); } if (removedFirstNewLine) { - insertText = '\n' + insertText; + textToInsert = '\n' + textToInsert; } if (removedLastNewLine) { - insertText += '\n'; + textToInsert += '\n'; } - if (document.queryCommandSupported('insertText')) { - inserted = document.execCommand('insertText', false, insertText); - } - if (!inserted) { - try { - document.execCommand("ms-beginUndoUnit"); - } catch (error) {} - textArea.value = this.replaceRange(text, textArea.selectionStart, textArea.selectionEnd, insertText); - try { - document.execCommand("ms-endUndoUnit"); - } catch (error) {} - } - return this.moveCursor(textArea, tag, wrap, removedLastNewLine); -}; + insertText(textArea, textToInsert); + return moveCursor(textArea, tag, wrap, removedLastNewLine); +} -textUtils.moveCursor = function(textArea, tag, wrapped, removedLastNewLine) { - var pos; - if (!textArea.setSelectionRange) { - return; - } - if (textArea.selectionStart === textArea.selectionEnd) { - if (wrapped) { - pos = textArea.selectionStart - tag.length; - } else { - pos = textArea.selectionStart; - } - - if (removedLastNewLine) { - pos -= 1; - } - - return textArea.setSelectionRange(pos, pos); - } -}; - -textUtils.updateText = function(textArea, tag, blockTag, wrap) { +function updateText(textArea, tag, blockTag, wrap) { var $textArea, selected, text; $textArea = $(textArea); textArea = $textArea.get(0); text = $textArea.val(); - selected = this.selectedText(text, textArea); + selected = selectedText(text, textArea); $textArea.focus(); - return this.insertText(textArea, text, tag, blockTag, selected, wrap); -}; + return insertMarkdownText(textArea, text, tag, blockTag, selected, wrap); +} -textUtils.init = function(form) { - var self; - self = this; +function replaceRange(s, start, end, substitute) { + return s.substring(0, start) + substitute + s.substring(end); +} + +export function addMarkdownListeners(form) { return $('.js-md', form).off('click').on('click', function() { - var $this; - $this = $(this); - return self.updateText($this.closest('.md-area').find('textarea'), $this.data('mdTag'), $this.data('mdBlock'), !$this.data('mdPrepend')); + const $this = $(this); + return updateText($this.closest('.md-area').find('textarea'), $this.data('mdTag'), $this.data('mdBlock'), !$this.data('mdPrepend')); }); -}; +} -textUtils.removeListeners = function(form) { +export function removeMarkdownListeners(form) { return $('.js-md', form).off('click'); -}; - -textUtils.replaceRange = function(s, start, end, substitute) { - return s.substring(0, start) + substitute + s.substring(end); -}; - -export default textUtils; +} diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index e68c1012199..1e066b69c6e 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -140,7 +140,11 @@ module Ci next if build.retries_max.zero? if build.retries_count < build.retries_max - Ci::Build.retry(build, build.user) + begin + Ci::Build.retry(build, build.user) + rescue Gitlab::Access::AccessDeniedError => ex + Rails.logger.error "Unable to auto-retry job #{build.id}: #{ex}" + end end end diff --git a/changelogs/unreleased/42880-loss-of-input-text-on-comments-after-preview.yml b/changelogs/unreleased/42880-loss-of-input-text-on-comments-after-preview.yml new file mode 100644 index 00000000000..0e892a51bc5 --- /dev/null +++ b/changelogs/unreleased/42880-loss-of-input-text-on-comments-after-preview.yml @@ -0,0 +1,5 @@ +--- +title: Fix Firefox stealing formatting characters on issue notes +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/fix-ci-job-auto-retry.yml b/changelogs/unreleased/fix-ci-job-auto-retry.yml new file mode 100644 index 00000000000..442126461f0 --- /dev/null +++ b/changelogs/unreleased/fix-ci-job-auto-retry.yml @@ -0,0 +1,5 @@ +--- +title: Prevent auto-retry AccessDenied error from stopping transition to failed +merge_request: 17862 +author: +type: fixed diff --git a/changelogs/unreleased/update-spec-import-path-for-vue-mount-component-helper.yml b/changelogs/unreleased/update-spec-import-path-for-vue-mount-component-helper.yml new file mode 100644 index 00000000000..9c13bfbaf6f --- /dev/null +++ b/changelogs/unreleased/update-spec-import-path-for-vue-mount-component-helper.yml @@ -0,0 +1,5 @@ +--- +title: Update spec import path for vue mount component helper +merge_request: 17880 +author: George Tsiolis +type: performance diff --git a/config/initializers/lograge.rb b/config/initializers/lograge.rb index 114c1cb512f..49fdd23064c 100644 --- a/config/initializers/lograge.rb +++ b/config/initializers/lograge.rb @@ -1,3 +1,21 @@ +# Monkey patch lograge until https://github.com/roidrage/lograge/pull/241 is released +module Lograge + class RequestLogSubscriber < ActiveSupport::LogSubscriber + def strip_query_string(path) + index = path.index('?') + index ? path[0, index] : path + end + + def extract_location + location = Thread.current[:lograge_location] + return {} unless location + + Thread.current[:lograge_location] = nil + { location: strip_query_string(location) } + end + end +end + # Only use Lograge for Rails unless Sidekiq.server? filename = File.join(Rails.root, 'log', "#{Rails.env}_json.log") diff --git a/doc/development/new_fe_guide/development/performance.md b/doc/development/new_fe_guide/development/performance.md index 26b07874f0f..244dfb3756f 100644 --- a/doc/development/new_fe_guide/development/performance.md +++ b/doc/development/new_fe_guide/development/performance.md @@ -1,3 +1,16 @@ # Performance -> TODO: Add content +## Monitoring + +We have a performance dashboard available in one of our [grafana instances](https://performance.gprd.gitlab.com/dashboard/db/sitespeed-page-summary?orgId=1). This dashboard automatically aggregates metric data from [sitespeed.io](https://sitespeed.io) every 6 hours. These changes are displayed after a set number of pages are aggregated. + +These pages can be found inside a text file in the gitlab-build-images [repository](https://gitlab.com/gitlab-org/gitlab-build-images) called [gitlab.txt](https://gitlab.com/gitlab-org/gitlab-build-images/blob/master/scripts/gitlab.txt) +Any frontend engineer can contribute to this dashboard. They can contribute by adding or removing urls of pages from this text file. Please have a [frontend monitoring expert](https://about.gitlab.com/team) review your changes before assigning to a maintainer of the `gitlab-build-images` project. The changes will go live on the next scheduled run after the changes are merged into `master`. + +There are 3 recommended high impact metrics to review on each page + +* [First visual change](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint) +* [Speed Index](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index) +* [Visual Complete 95%](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index) + +For these metrics, lower numbers are better as it means that the website is more performant. diff --git a/doc/install/kubernetes/index.md b/doc/install/kubernetes/index.md index 3a1707a54a1..aa9b8777359 100644 --- a/doc/install/kubernetes/index.md +++ b/doc/install/kubernetes/index.md @@ -10,7 +10,7 @@ should be deployed, upgraded, and configured. ## Chart Overview * **[GitLab-Omnibus](gitlab_omnibus.md)**: The best way to run GitLab on Kubernetes today, suited for small deployments. The chart is in beta and will be deprecated by the [cloud native GitLab chart](#cloud-native-gitlab-chart). -* **[Cloud Native GitLab Chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md)**: The next generation GitLab chart, currently in development. Will support large deployments with horizontal scaling of individual GitLab components. +* **[Cloud Native GitLab Chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md)**: The next generation GitLab chart, currently in alpha. Will support large deployments with horizontal scaling of individual GitLab components. * Other Charts * [GitLab Runner Chart](gitlab_runner_chart.md): For deploying just the GitLab Runner. * [Advanced GitLab Installation](gitlab_chart.md): Deprecated, being replaced by the [cloud native GitLab chart](#cloud-native-gitlab-chart). Provides additional deployment options, but provides less functionality out-of-the-box. @@ -35,7 +35,7 @@ By offering individual containers and charts, we will be able to provide a numbe * Potential for rolling updates and canaries within a service, * and plenty more. -This is a large project and will be worked on over the span of multiple releases. For the most up-to-date status and release information, please see our [tracking issue](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/2420). We are planning to launch this chart in beta by the end of 2017. +Presently this chart is available in alpha for testing, and not recommended for production use. Learn more about the [cloud native GitLab chart here ](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md) and [here [Video]](https://youtu.be/Z6jWR8Z8dv8). diff --git a/doc/user/project/merge_requests/maintainer_access.md b/doc/user/project/merge_requests/maintainer_access.md index 7feccc28f6b..c9763a3fe02 100644 --- a/doc/user/project/merge_requests/maintainer_access.md +++ b/doc/user/project/merge_requests/maintainer_access.md @@ -1,12 +1,17 @@ # Allow maintainer pushes for merge requests across forks +> [Introduced][ce-17395] in GitLab 10.6. + This feature is available for merge requests across forked projects that are -publicly accessible. It makes it easier for maintainers of projects to collaborate -on merge requests across forks. +publicly accessible. It makes it easier for maintainers of projects to +collaborate on merge requests across forks. -When enabling this feature for a merge request, you give can give members with push access to the target project rights to edit files on the source branch of the merge request. +When enabled for a merge request, members with merge access to the target +branch of the project will be granted write permissions to the source branch +of the merge request. -The feature can only be enabled by users who already have push access to the source project. And only lasts while the merge request is open. +The feature can only be enabled by users who already have push access to the +source project, and only lasts while the merge request is open. Enable this functionality while creating a merge request: diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index 35875487da8..2f2506f08fb 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -4,6 +4,7 @@ module QA class Show < Page::Base view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js' do element :merge_button + element :fast_forward_message, 'Fast-forward merge without a merge commit' end view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue' do @@ -12,19 +13,19 @@ module QA view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue' do element :mr_rebase_button - element :fast_forward_nessage, "Fast-forward merge is not possible" + element :no_fast_forward_message, 'Fast-forward merge is not possible' end def rebase! - wait(reload: false) do - click_element :mr_rebase_button + click_element :mr_rebase_button - has_text?("The source branch HEAD has recently changed.") + wait(reload: false) do + has_text?('Fast-forward merge without a merge commit') end end def fast_forward_possible? - !has_text?("Fast-forward merge is not possible") + !has_text?('Fast-forward merge is not possible') end def has_merge_button? @@ -34,10 +35,10 @@ module QA end def merge! - wait(reload: false) do - click_element :merge_button + click_element :merge_button - has_text?("The changes were merged into") + wait(reload: false) do + has_text?('The changes were merged into') end end end diff --git a/spec/javascripts/lib/utils/text_markdown_spec.js b/spec/javascripts/lib/utils/text_markdown_spec.js index a95a7e2a5be..ca0e7c395a0 100644 --- a/spec/javascripts/lib/utils/text_markdown_spec.js +++ b/spec/javascripts/lib/utils/text_markdown_spec.js @@ -1,4 +1,4 @@ -import textUtils from '~/lib/utils/text_markdown'; +import { insertMarkdownText } from '~/lib/utils/text_markdown'; describe('init markdown', () => { let textArea; @@ -21,7 +21,7 @@ describe('init markdown', () => { textArea.selectionStart = 0; textArea.selectionEnd = 0; - textUtils.insertText(textArea, textArea.value, '*', null, '', false); + insertMarkdownText(textArea, textArea.value, '*', null, '', false); expect(textArea.value).toEqual(`${initialValue}* `); }); @@ -32,7 +32,7 @@ describe('init markdown', () => { textArea.value = initialValue; textArea.setSelectionRange(initialValue.length, initialValue.length); - textUtils.insertText(textArea, textArea.value, '*', null, '', false); + insertMarkdownText(textArea, textArea.value, '*', null, '', false); expect(textArea.value).toEqual(`${initialValue}\n* `); }); @@ -43,7 +43,7 @@ describe('init markdown', () => { textArea.value = initialValue; textArea.setSelectionRange(initialValue.length, initialValue.length); - textUtils.insertText(textArea, textArea.value, '*', null, '', false); + insertMarkdownText(textArea, textArea.value, '*', null, '', false); expect(textArea.value).toEqual(`${initialValue}* `); }); @@ -54,7 +54,7 @@ describe('init markdown', () => { textArea.value = initialValue; textArea.setSelectionRange(initialValue.length, initialValue.length); - textUtils.insertText(textArea, textArea.value, '*', null, '', false); + insertMarkdownText(textArea, textArea.value, '*', null, '', false); expect(textArea.value).toEqual(`${initialValue}* `); }); diff --git a/spec/javascripts/notes/components/diff_file_header_spec.js b/spec/javascripts/notes/components/diff_file_header_spec.js index aed30a087a6..ef6d513444a 100644 --- a/spec/javascripts/notes/components/diff_file_header_spec.js +++ b/spec/javascripts/notes/components/diff_file_header_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import DiffFileHeader from '~/notes/components/diff_file_header.vue'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; -import mountComponent from '../../helpers/vue_mount_component_helper'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; const discussionFixture = 'merge_requests/diff_discussion.json'; diff --git a/spec/javascripts/notes/components/diff_with_note_spec.js b/spec/javascripts/notes/components/diff_with_note_spec.js index 7f1f4bf0bcd..f4ec7132dbd 100644 --- a/spec/javascripts/notes/components/diff_with_note_spec.js +++ b/spec/javascripts/notes/components/diff_with_note_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import DiffWithNote from '~/notes/components/diff_with_note.vue'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; -import mountComponent from '../../helpers/vue_mount_component_helper'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; const discussionFixture = 'merge_requests/diff_discussion.json'; const imageDiscussionFixture = 'merge_requests/image_diff_discussion.json'; diff --git a/spec/javascripts/pages/labels/components/promote_label_modal_spec.js b/spec/javascripts/pages/labels/components/promote_label_modal_spec.js index ba2e07f02f7..080158a8ee0 100644 --- a/spec/javascripts/pages/labels/components/promote_label_modal_spec.js +++ b/spec/javascripts/pages/labels/components/promote_label_modal_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import promoteLabelModal from '~/pages/projects/labels/components/promote_label_modal.vue'; import eventHub from '~/pages/projects/labels/event_hub'; import axios from '~/lib/utils/axios_utils'; -import mountComponent from '../../../helpers/vue_mount_component_helper'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; describe('Promote label modal', () => { let vm; diff --git a/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js b/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js index bf044fe8fb5..22956929e7b 100644 --- a/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js +++ b/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import promoteMilestoneModal from '~/pages/milestones/shared/components/promote_milestone_modal.vue'; import eventHub from '~/pages/milestones/shared/event_hub'; import axios from '~/lib/utils/axios_utils'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; describe('Promote milestone modal', () => { let vm; diff --git a/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js b/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js index 818ef0af3c2..3e708f865c8 100644 --- a/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js +++ b/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import toolbar from '~/vue_shared/components/markdown/toolbar.vue'; -import mountComponent from '../../../helpers/vue_mount_component_helper'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; describe('toolbar', () => { let vm; diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js index 8daaf018396..6fe95153204 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js @@ -3,9 +3,9 @@ import Vue from 'vue'; import LabelsSelect from '~/labels_select'; import baseComponent from '~/vue_shared/components/sidebar/labels_select/base.vue'; -import { mockConfig, mockLabels } from './mock_data'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import { mockConfig, mockLabels } from './mock_data'; const createComponent = (config = mockConfig) => { const Component = Vue.extend(baseComponent); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js index ec63ac306d0..f25c70db125 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js @@ -2,9 +2,9 @@ import Vue from 'vue'; import dropdownButtonComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_button.vue'; -import { mockConfig, mockLabels } from './mock_data'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import { mockConfig, mockLabels } from './mock_data'; const componentConfig = Object.assign({}, mockConfig, { fieldName: 'label_id[]', diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js index 5cb4bb6fea6..ce559fe0335 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js @@ -2,9 +2,9 @@ import Vue from 'vue'; import dropdownCreateLabelComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_create_label.vue'; -import { mockSuggestedColors } from './mock_data'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import { mockSuggestedColors } from './mock_data'; const createComponent = (headerTitle) => { const Component = Vue.extend(dropdownCreateLabelComponent); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js index 0f4fa716f8a..debeab25bd6 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js @@ -2,9 +2,9 @@ import Vue from 'vue'; import dropdownFooterComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_footer.vue'; -import { mockConfig } from './mock_data'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import { mockConfig } from './mock_data'; const createComponent = ( labelsWebUrl = mockConfig.labelsWebUrl, diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js index 325fa47c957..cdf234bb0c4 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import dropdownHeaderComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_header.vue'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; const createComponent = () => { const Component = Vue.extend(dropdownHeaderComponent); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_hidden_input_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_hidden_input_spec.js index 703b87498c7..88733922a59 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_hidden_input_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_hidden_input_spec.js @@ -2,9 +2,9 @@ import Vue from 'vue'; import dropdownHiddenInputComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_hidden_input.vue'; -import { mockLabels } from './mock_data'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import { mockLabels } from './mock_data'; const createComponent = (name = 'label_id[]', label = mockLabels[0]) => { const Component = Vue.extend(dropdownHiddenInputComponent); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js index 69e11d966c2..57608d957e7 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import dropdownSearchInputComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_search_input.vue'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; const createComponent = () => { const Component = Vue.extend(dropdownSearchInputComponent); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js index c3580933072..7c3d2711f65 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import dropdownTitleComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_title.vue'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; const createComponent = (canEdit = true) => { const Component = Vue.extend(dropdownTitleComponent); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js index 93b42795bea..39040670a87 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js @@ -2,9 +2,9 @@ import Vue from 'vue'; import dropdownValueCollapsedComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed.vue'; -import { mockLabels } from './mock_data'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import { mockLabels } from './mock_data'; const createComponent = (labels = mockLabels) => { const Component = Vue.extend(dropdownValueCollapsedComponent); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js index 66e0957b431..4397b00acfa 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js @@ -2,9 +2,9 @@ import Vue from 'vue'; import dropdownValueComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_value.vue'; -import { mockConfig, mockLabels } from './mock_data'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import mountComponent from '../../../../helpers/vue_mount_component_helper'; +import { mockConfig, mockLabels } from './mock_data'; const createComponent = ( labels = mockLabels, diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 9da3de7a828..30a352fd090 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -2101,6 +2101,35 @@ describe Ci::Build do subject.drop! end + + context 'when retry service raises Gitlab::Access::AccessDeniedError exception' do + let(:retry_service) { Ci::RetryBuildService.new(subject.project, subject.user) } + + before do + allow_any_instance_of(Ci::RetryBuildService) + .to receive(:execute) + .with(subject) + .and_raise(Gitlab::Access::AccessDeniedError) + allow(Rails.logger).to receive(:error) + end + + it 'handles raised exception' do + expect { subject.drop! }.not_to raise_exception(Gitlab::Access::AccessDeniedError) + end + + it 'logs the error' do + subject.drop! + + expect(Rails.logger) + .to have_received(:error) + .with(a_string_matching("Unable to auto-retry job #{subject.id}")) + end + + it 'fails the job' do + subject.drop! + expect(subject.failed?).to be_truthy + end + end end context 'when build is not configured to be retried' do |