From 7d66b7fbccc0e11346e00d839e5efb640d54022d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Genz?= Date: Wed, 20 Sep 2017 11:09:41 +0000 Subject: [PATCH 001/263] fix minor spelling mistakes --- doc/install/requirements.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/install/requirements.md b/doc/install/requirements.md index f672b358096..17fe80fa93d 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -82,11 +82,11 @@ errors during usage. We recommend having at least 2GB of swap on your server, even if you currently have enough available RAM. Having swap will help reduce the chance of errors occurring -if your available memory changes. We also recommend [configuring the kernels swappiness setting](https://askubuntu.com/a/103916) +if your available memory changes. We also recommend [configuring the kernel's swappiness setting](https://askubuntu.com/a/103916) to a low value like `10` to make the most of your RAM while still having the swap available when needed. -Notice: The 25 workers of Sidekiq will show up as separate processes in your process overview (such as top or htop) but they share the same RAM allocation since Sidekiq is a multithreaded application. Please see the section below about Unicorn workers for information about many you need of those. +Notice: The 25 workers of Sidekiq will show up as separate processes in your process overview (such as top or htop) but they share the same RAM allocation since Sidekiq is a multithreaded application. Please see the section below about Unicorn workers for information about how many you need of those. ## Database From e4708e28a81e7372f30bda15ea9c3550f9d79cf3 Mon Sep 17 00:00:00 2001 From: Winnie Hellmann Date: Thu, 21 Sep 2017 12:08:34 +0200 Subject: [PATCH 002/263] Avoid wrapping users in dropdown --- app/assets/stylesheets/framework/dropdowns.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 2bcd23a15e6..c0d8e6c328c 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -779,6 +779,14 @@ white-space: normal; width: 100%; + &.dropdown-menu-user-link { + white-space: nowrap; + + .dropdown-menu-user-username { + display: block; + } + } + // make sure the text color is not overriden &.text-danger { color: $brand-danger; From 093e708bf8157052eb204577da3bac38b7c4e6b5 Mon Sep 17 00:00:00 2001 From: Mark Fletcher Date: Thu, 21 Sep 2017 13:48:44 +1000 Subject: [PATCH 003/263] Fix auto devops typos in Pipeline Settings view --- app/views/projects/pipelines_settings/_show.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml index 21d01242c0e..77211099830 100644 --- a/app/views/projects/pipelines_settings/_show.html.haml +++ b/app/views/projects/pipelines_settings/_show.html.haml @@ -26,7 +26,8 @@ %strong Disable Auto DevOps %br %span.descr - An explicit .gitlab-ci.yml needs to be specified before you can begin using Continious Integration and Delivery. + An explicit .gitlab-ci.yml needs to be specified before you can begin using Continuous Integration and Delivery. + .radio = form.label :enabled_nil do = form.radio_button :enabled, '' From 9025ce14d9c69443d8e412840c353b992048970b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Tue, 19 Sep 2017 16:50:26 +0200 Subject: [PATCH 004/263] Automatically set a :type for specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/spec_helper.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 92735336572..dbf05b7f004 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -64,8 +64,16 @@ RSpec.configure do |config| config.infer_spec_type_from_file_location! - config.define_derived_metadata(file_path: %r{/spec/requests/(ci/)?api/}) do |metadata| - metadata[:api] = true + config.define_derived_metadata(file_path: %r{/spec/}) do |metadata| + location = metadata[:location] + + metadata[:api] = true if location =~ %r{/spec/requests/api/} + + # do not overwrite type if it's already set + next if metadata.key?(:type) + + match = location.match(%r{/spec/([^/]+)/}) + metadata[:type] = match[1].singularize.to_sym if match end config.raise_errors_for_deprecations! From 7ce70dd5a046048ef13eb5f93ece8f149bfbaea3 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 14 Sep 2017 20:25:48 +0100 Subject: [PATCH 005/263] Dynamically create offset for sticky bar --- app/assets/javascripts/lib/utils/sticky.js | 30 ++++++++++++++++++---- app/assets/stylesheets/pages/diff.scss | 9 ++----- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/lib/utils/sticky.js b/app/assets/javascripts/lib/utils/sticky.js index 283c0ec0410..f8f0a43f1cc 100644 --- a/app/assets/javascripts/lib/utils/sticky.js +++ b/app/assets/javascripts/lib/utils/sticky.js @@ -1,14 +1,34 @@ -export const isSticky = (el, scrollY, stickyTop) => { +export const createPlaceholder = () => { + const placeholder = document.createElement('div'); + placeholder.classList.add('sticky-placeholder'); + + return placeholder; +}; + +export const isSticky = (el, scrollY, stickyTop, insertPlaceholder) => { const top = Math.floor(el.offsetTop - scrollY); - if (top <= stickyTop) { + if (top <= stickyTop && !el.classList.contains('is-stuck')) { + const placeholder = insertPlaceholder ? createPlaceholder(el) : null; + const heightBefore = el.offsetHeight; + el.classList.add('is-stuck'); - } else { + + if (insertPlaceholder) { + el.parentNode.insertBefore(placeholder, el.nextElementSibling); + + placeholder.style.height = `${heightBefore - el.offsetHeight}px`; + } + } else if (top > stickyTop && el.classList.contains('is-stuck')) { el.classList.remove('is-stuck'); + + if (insertPlaceholder && el.nextElementSibling.classList.contains('sticky-placeholder')) { + el.nextElementSibling.remove(); + } } }; -export default (el) => { +export default (el, insertPlaceholder = true) => { if (!el) return; const computedStyle = window.getComputedStyle(el); @@ -17,7 +37,7 @@ export default (el) => { const stickyTop = parseInt(computedStyle.top, 10); - document.addEventListener('scroll', () => isSticky(el, window.scrollY, stickyTop), { + document.addEventListener('scroll', () => isSticky(el, window.scrollY, stickyTop, insertPlaceholder), { passive: true, }); }; diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 951580ea1fe..5dbf44073b5 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -451,7 +451,7 @@ } .files { - margin-top: -1px; + margin-top: 1px; .diff-file:last-child { margin-bottom: 0; @@ -586,11 +586,6 @@ top: 76px; } - + .files, - + .alert { - margin-top: 1px; - } - &:not(.is-stuck) .diff-stats-additions-deletions-collapsed { display: none; } @@ -608,7 +603,7 @@ + .files, + .alert { - margin-top: 32px; + // margin-top: 32px; } } } From 734bb736258293e213fb0580f1f0b15618a78bc2 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 15 Sep 2017 09:01:58 +0100 Subject: [PATCH 006/263] fixed and added specs for removing placeholder element --- spec/javascripts/lib/utils/sticky_spec.js | 40 +++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/spec/javascripts/lib/utils/sticky_spec.js b/spec/javascripts/lib/utils/sticky_spec.js index c3ee3ef9825..5ffc41589e5 100644 --- a/spec/javascripts/lib/utils/sticky_spec.js +++ b/spec/javascripts/lib/utils/sticky_spec.js @@ -4,12 +4,25 @@ describe('sticky', () => { const el = { offsetTop: 0, classList: {}, + parentNode: {}, + nextElementSibling: {}, }; + let isStuck = false; beforeEach(() => { el.offsetTop = 0; - el.classList.add = jasmine.createSpy('spy'); - el.classList.remove = jasmine.createSpy('spy'); + el.classList.add = jasmine.createSpy('classListAdd'); + el.classList.remove = jasmine.createSpy('classListRemove'); + el.classList.contains = jasmine.createSpy('classListContains').and.callFake(() => isStuck); + el.parentNode.insertBefore = jasmine.createSpy('insertBefore'); + el.nextElementSibling.remove = jasmine.createSpy('nextElementSibling'); + el.nextElementSibling.classList = { + contains: jasmine.createSpy('classListContains').and.returnValue(true), + }; + }); + + afterEach(() => { + isStuck = false; }); describe('classList.remove', () => { @@ -21,7 +34,9 @@ describe('sticky', () => { ).not.toHaveBeenCalled(); }); - it('calls classList.remove when not stuck', () => { + it('calls classList.remove when no longer stuck', () => { + isStuck = true; + el.offsetTop = 10; isSticky(el, 0, 0); @@ -29,6 +44,17 @@ describe('sticky', () => { el.classList.remove, ).toHaveBeenCalledWith('is-stuck'); }); + + it('removes placeholder when no longer stuck', () => { + isStuck = true; + + el.offsetTop = 10; + isSticky(el, 0, 0, true); + + expect( + el.nextElementSibling.remove, + ).toHaveBeenCalled(); + }); }); describe('classList.add', () => { @@ -48,5 +74,13 @@ describe('sticky', () => { el.classList.add, ).not.toHaveBeenCalled(); }); + + it('inserts placeholder element when stuck', () => { + isSticky(el, 0, 0, true); + + expect( + el.parentNode.insertBefore, + ).toHaveBeenCalled(); + }); }); }); From 9f3227645442017e3518e2b0ba3e9270ebabfa06 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 19 Sep 2017 13:43:04 +0100 Subject: [PATCH 007/263] Add context tabs to dashboard/projects This allows users to quickly switch between all projects they have access to & there own namespace projects. These tabs also keep the same filtering/search options selected so the user can quickly switch between the two different contexts. Closes #29045 --- app/views/dashboard/projects/_nav.html.haml | 8 ++++++++ app/views/dashboard/projects/index.html.haml | 1 + .../unreleased/project-page-clearer.yml | 5 +++++ spec/features/dashboard/projects_spec.rb | 19 +++++++++++++++++++ .../dashboard/projects/_nav.html.haml.rb | 17 +++++++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 app/views/dashboard/projects/_nav.html.haml create mode 100644 changelogs/unreleased/project-page-clearer.yml create mode 100644 spec/views/dashboard/projects/_nav.html.haml.rb diff --git a/app/views/dashboard/projects/_nav.html.haml b/app/views/dashboard/projects/_nav.html.haml new file mode 100644 index 00000000000..697211d7ce8 --- /dev/null +++ b/app/views/dashboard/projects/_nav.html.haml @@ -0,0 +1,8 @@ +.top-area + %ul.nav-links + = nav_link(html_options: { class: ("active" unless params[:personal].present?) }) do + = link_to dashboard_projects_path do + #{ s_('DashboardProjects|All') } + = nav_link(html_options: { class: ("active" if params[:personal].present?) }) do + = link_to filter_projects_path(personal: true) do + #{ s_('DashboardProjects|Personal') } diff --git a/app/views/dashboard/projects/index.html.haml b/app/views/dashboard/projects/index.html.haml index a4dc49d2120..985871a888c 100644 --- a/app/views/dashboard/projects/index.html.haml +++ b/app/views/dashboard/projects/index.html.haml @@ -12,6 +12,7 @@ %div{ class: container_class } - if has_projects_or_name?(@projects, params) = render 'dashboard/projects_head' + = render 'nav' = render 'projects' - else = render "zero_authorized_projects" diff --git a/changelogs/unreleased/project-page-clearer.yml b/changelogs/unreleased/project-page-clearer.yml new file mode 100644 index 00000000000..7db01373360 --- /dev/null +++ b/changelogs/unreleased/project-page-clearer.yml @@ -0,0 +1,5 @@ +--- +title: Added tabs to dashboard/projects to easily switch to personal projects +merge_request: +author: +type: added diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 9a7b8e3ba6b..4da95ccc169 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -50,6 +50,25 @@ feature 'Dashboard Projects' do end end + context 'when on Your projects tab' do + it 'shows all projects by default' do + visit dashboard_projects_path + + expect(page).to have_content(project.name) + end + + it 'shows personal projects on personal projects tab', :js do + project3 = create(:project, namespace: user.namespace) + + visit dashboard_projects_path + + click_link 'Personal' + + expect(page).not_to have_content(project.name) + expect(page).to have_content(project3.name) + end + end + context 'when on Starred projects tab' do it 'shows only starred projects' do user.toggle_star(project2) diff --git a/spec/views/dashboard/projects/_nav.html.haml.rb b/spec/views/dashboard/projects/_nav.html.haml.rb new file mode 100644 index 00000000000..f6a8ca13040 --- /dev/null +++ b/spec/views/dashboard/projects/_nav.html.haml.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe 'dashboard/projects/_nav.html.haml' do + it 'highlights All tab by default' do + render + + expect(rendered).to have_css('li.active a', text: 'All') + end + + it 'highlights Personal tab personal param is present' do + controller.params[:personal] = true + + render + + expect(rendered).to have_css('li.active a', text: 'Personal') + end +end From eab0ca8a0b2950dbbcf6662c34b2fc8313ba9bde Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 21 Sep 2017 11:03:14 +0100 Subject: [PATCH 008/263] Fixes dashboard/projects empty state showing when viewing personal projects This was caused by the `@projects` value being empty when the current user does not have any personal projects. --- app/helpers/projects_helper.rb | 4 ++-- app/views/dashboard/projects/index.html.haml | 2 +- spec/helpers/projects_helper_spec.rb | 12 ++++++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index ddeff490d3a..21fb17e06d6 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -239,8 +239,8 @@ module ProjectsHelper end end - def has_projects_or_name?(projects, params) - !!(params[:name] || any_projects?(projects)) + def show_projects?(projects, params) + !!(params[:personal] || params[:name] || any_projects?(projects)) end private diff --git a/app/views/dashboard/projects/index.html.haml b/app/views/dashboard/projects/index.html.haml index 985871a888c..57a4da353fe 100644 --- a/app/views/dashboard/projects/index.html.haml +++ b/app/views/dashboard/projects/index.html.haml @@ -10,7 +10,7 @@ = render "projects/last_push" %div{ class: container_class } - - if has_projects_or_name?(@projects, params) + - if show_projects?(@projects, params) = render 'dashboard/projects_head' = render 'nav' = render 'projects' diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index a76c75e0c08..7ded95d01af 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -420,22 +420,26 @@ describe ProjectsHelper do end end - describe '#has_projects_or_name?' do + describe '#show_projects' do let(:projects) do create(:project) Project.all end it 'returns true when there are projects' do - expect(helper.has_projects_or_name?(projects, {})).to eq(true) + expect(helper.show_projects?(projects, {})).to eq(true) end it 'returns true when there are no projects but a name is given' do - expect(helper.has_projects_or_name?(Project.none, name: 'foo')).to eq(true) + expect(helper.show_projects?(Project.none, name: 'foo')).to eq(true) + end + + it 'returns true when there are no projects but personal is present' do + expect(helper.show_projects?(Project.none, personal: 'true')).to eq(true) end it 'returns false when there are no projects and there is no name' do - expect(helper.has_projects_or_name?(Project.none, {})).to eq(false) + expect(helper.show_projects?(Project.none, {})).to eq(false) end end From 8eb2d741ad038a80759b8db94ad475ad86f46543 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 22 Sep 2017 12:26:23 +0100 Subject: [PATCH 009/263] simplify link_to call --- app/views/dashboard/projects/_nav.html.haml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/views/dashboard/projects/_nav.html.haml b/app/views/dashboard/projects/_nav.html.haml index 697211d7ce8..3701e1c0578 100644 --- a/app/views/dashboard/projects/_nav.html.haml +++ b/app/views/dashboard/projects/_nav.html.haml @@ -1,8 +1,6 @@ .top-area %ul.nav-links = nav_link(html_options: { class: ("active" unless params[:personal].present?) }) do - = link_to dashboard_projects_path do - #{ s_('DashboardProjects|All') } + = link_to s_('DashboardProjects|All'), dashboard_projects_path = nav_link(html_options: { class: ("active" if params[:personal].present?) }) do - = link_to filter_projects_path(personal: true) do - #{ s_('DashboardProjects|Personal') } + = link_to s_('DashboardProjects|Personal'), filter_projects_path(personal: true) From da6ff6519818fafe38433599b663a4aeff1007c1 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 21 Sep 2017 08:04:25 +0100 Subject: [PATCH 010/263] spec fixes --- app/assets/stylesheets/test.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/assets/stylesheets/test.scss b/app/assets/stylesheets/test.scss index 7d9f3da79c5..06733b7f1a9 100644 --- a/app/assets/stylesheets/test.scss +++ b/app/assets/stylesheets/test.scss @@ -15,3 +15,9 @@ -ms-animation: none !important; animation: none !important; } + +// Disable sticky changes bar for tests +.diff-files-changed { + position: relative !important; + top: 0 !important; +} From 9647913acbdb4f65ec0d943bcbc72311dac992ec Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Fri, 22 Sep 2017 13:15:17 +0000 Subject: [PATCH 011/263] Update gitlab-shell to 5.9.2 See gitlab-shell!169 --- GITLAB_SHELL_VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index b3d91f9cfc0..da902181863 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -5.9.0 +5.9.2 From 36a917e1a8e5369e349cf467a29226c0f6fa0cac Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Fri, 22 Sep 2017 16:42:05 +0300 Subject: [PATCH 012/263] RepoEditor: Implement line and range linking. --- app/assets/javascripts/line_highlighter.js | 267 +++++++++--------- .../repo/components/repo_preview.vue | 14 +- 2 files changed, 143 insertions(+), 138 deletions(-) diff --git a/app/assets/javascripts/line_highlighter.js b/app/assets/javascripts/line_highlighter.js index 7400c22543f..a16d00b5cef 100644 --- a/app/assets/javascripts/line_highlighter.js +++ b/app/assets/javascripts/line_highlighter.js @@ -28,148 +28,149 @@ // // // -(function() { - this.LineHighlighter = (function() { - // CSS class applied to highlighted lines - LineHighlighter.prototype.highlightClass = 'hll'; - // Internal copy of location.hash so we're not dependent on `location` in tests - LineHighlighter.prototype._hash = ''; +const LineHighlighter = function(options = {}) { + options.highlightLineClass = options.highlightLineClass || 'hll'; + options.fileHolderSelector = options.fileHolderSelector || '.file-holder'; + options.scrollFileHolder = options.scrollFileHolder || false; + options.hash = options.hash || location.hash; - function LineHighlighter(hash) { - if (hash == null) { - // Initialize a LineHighlighter object - // - // hash - String URL hash for dependency injection in tests - hash = location.hash; + this.options = options; + this._hash = options.hash; + this.highlightLineClass = options.highlightLineClass; + this.setHash = this.setHash.bind(this); + this.highlightLine = this.highlightLine.bind(this); + this.clickHandler = this.clickHandler.bind(this); + this.highlightHash = this.highlightHash.bind(this); + + this.bindEvents(); + this.highlightHash(); +}; + +LineHighlighter.prototype.bindEvents = function() { + const $fileHolder = $(this.options.fileHolderSelector); + + $fileHolder.on('click', 'a[data-line-number]', this.clickHandler); + $fileHolder.on('highlight:line', this.highlightHash); +}; + +LineHighlighter.prototype.highlightHash = function() { + var range; + + if (this._hash !== '') { + range = this.hashToRange(this._hash); + + if (range[0]) { + this.highlightRange(range); + const lineSelector = `#L${range[0]}`; + const scrollOptions = { + // Scroll to the first highlighted line on initial load + // Offset -50 for the sticky top bar, and another -100 for some context + offset: -150 + }; + if (this.options.scrollFileHolder) { + $(this.options.fileHolderSelector).scrollTo(lineSelector, scrollOptions); + } else { + $.scrollTo(lineSelector, scrollOptions); } - this.setHash = this.setHash.bind(this); - this.highlightLine = this.highlightLine.bind(this); - this.clickHandler = this.clickHandler.bind(this); - this.highlightHash = this.highlightHash.bind(this); - this._hash = hash; - this.bindEvents(); - this.highlightHash(); } + } +}; - LineHighlighter.prototype.bindEvents = function() { - const $fileHolder = $('.file-holder'); - $fileHolder.on('click', 'a[data-line-number]', this.clickHandler); - $fileHolder.on('highlight:line', this.highlightHash); - }; +LineHighlighter.prototype.clickHandler = function(event) { + var current, lineNumber, range; + event.preventDefault(); + this.clearHighlight(); + lineNumber = $(event.target).closest('a').data('line-number'); + current = this.hashToRange(this._hash); + if (!(current[0] && event.shiftKey)) { + // If there's no current selection, or there is but Shift wasn't held, + // treat this like a single-line selection. + this.setHash(lineNumber); + return this.highlightLine(lineNumber); + } else if (event.shiftKey) { + if (lineNumber < current[0]) { + range = [lineNumber, current[0]]; + } else { + range = [current[0], lineNumber]; + } + this.setHash(range[0], range[1]); + return this.highlightRange(range); + } +}; - LineHighlighter.prototype.highlightHash = function() { - var range; - if (this._hash !== '') { - range = this.hashToRange(this._hash); - if (range[0]) { - this.highlightRange(range); - $.scrollTo("#L" + range[0], { - // Scroll to the first highlighted line on initial load - // Offset -50 for the sticky top bar, and another -100 for some context - offset: -150 - }); - } - } - }; +LineHighlighter.prototype.clearHighlight = function() { + return $("." + this.highlightLineClass).removeClass(this.highlightLineClass); +}; - LineHighlighter.prototype.clickHandler = function(event) { - var current, lineNumber, range; - event.preventDefault(); - this.clearHighlight(); - lineNumber = $(event.target).closest('a').data('line-number'); - current = this.hashToRange(this._hash); - if (!(current[0] && event.shiftKey)) { - // If there's no current selection, or there is but Shift wasn't held, - // treat this like a single-line selection. - this.setHash(lineNumber); - return this.highlightLine(lineNumber); - } else if (event.shiftKey) { - if (lineNumber < current[0]) { - range = [lineNumber, current[0]]; - } else { - range = [current[0], lineNumber]; - } - this.setHash(range[0], range[1]); - return this.highlightRange(range); - } - }; +// Convert a URL hash String into line numbers +// +// hash - Hash String +// +// Examples: +// +// hashToRange('#L5') # => [5, null] +// hashToRange('#L5-15') # => [5, 15] +// hashToRange('#foo') # => [null, null] +// +// Returns an Array +LineHighlighter.prototype.hashToRange = function(hash) { + var first, last, matches; + // ?L(\d+)(?:-(\d+))?$/) + matches = hash.match(/^#?L(\d+)(?:-(\d+))?$/); + if (matches && matches.length) { + first = parseInt(matches[1], 10); + last = matches[2] ? parseInt(matches[2], 10) : null; + return [first, last]; + } else { + return [null, null]; + } +}; - LineHighlighter.prototype.clearHighlight = function() { - return $("." + this.highlightClass).removeClass(this.highlightClass); - // Unhighlight previously highlighted lines - }; +// Highlight a single line +// +// lineNumber - Line number to highlight +LineHighlighter.prototype.highlightLine = function(lineNumber) { + return $("#LC" + lineNumber).addClass(this.highlightLineClass); +}; - // Convert a URL hash String into line numbers - // - // hash - Hash String - // - // Examples: - // - // hashToRange('#L5') # => [5, null] - // hashToRange('#L5-15') # => [5, 15] - // hashToRange('#foo') # => [null, null] - // - // Returns an Array - LineHighlighter.prototype.hashToRange = function(hash) { - var first, last, matches; - // ?L(\d+)(?:-(\d+))?$/) - matches = hash.match(/^#?L(\d+)(?:-(\d+))?$/); - if (matches && matches.length) { - first = parseInt(matches[1], 10); - last = matches[2] ? parseInt(matches[2], 10) : null; - return [first, last]; - } else { - return [null, null]; - } - }; +// Highlight all lines within a range +// +// range - Array containing the starting and ending line numbers +LineHighlighter.prototype.highlightRange = function(range) { + var i, lineNumber, ref, ref1, results; + if (range[1]) { + results = []; + for (lineNumber = i = ref = range[0], ref1 = range[1]; ref <= ref1 ? i <= ref1 : i >= ref1; lineNumber = ref <= ref1 ? (i += 1) : (i -= 1)) { + results.push(this.highlightLine(lineNumber)); + } + return results; + } else { + return this.highlightLine(range[0]); + } +}; - // Highlight a single line - // - // lineNumber - Line number to highlight - LineHighlighter.prototype.highlightLine = function(lineNumber) { - return $("#LC" + lineNumber).addClass(this.highlightClass); - }; +// Set the URL hash string +LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) { + var hash; + if (lastLineNumber) { + hash = "#L" + firstLineNumber + "-" + lastLineNumber; + } else { + hash = "#L" + firstLineNumber; + } + this._hash = hash; + return this.__setLocationHash__(hash); +}; - // Highlight all lines within a range - // - // range - Array containing the starting and ending line numbers - LineHighlighter.prototype.highlightRange = function(range) { - var i, lineNumber, ref, ref1, results; - if (range[1]) { - results = []; - for (lineNumber = i = ref = range[0], ref1 = range[1]; ref <= ref1 ? i <= ref1 : i >= ref1; lineNumber = ref <= ref1 ? (i += 1) : (i -= 1)) { - results.push(this.highlightLine(lineNumber)); - } - return results; - } else { - return this.highlightLine(range[0]); - } - }; +// Make the actual hash change in the browser +// +// This method is stubbed in tests. +LineHighlighter.prototype.__setLocationHash__ = function(value) { + return history.pushState({ + url: value + // We're using pushState instead of assigning location.hash directly to + // prevent the page from scrolling on the hashchange event + }, document.title, value); +}; - // Set the URL hash string - LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) { - var hash; - if (lastLineNumber) { - hash = "#L" + firstLineNumber + "-" + lastLineNumber; - } else { - hash = "#L" + firstLineNumber; - } - this._hash = hash; - return this.__setLocationHash__(hash); - }; - - // Make the actual hash change in the browser - // - // This method is stubbed in tests. - LineHighlighter.prototype.__setLocationHash__ = function(value) { - return history.pushState({ - url: value - // We're using pushState instead of assigning location.hash directly to - // prevent the page from scrolling on the hashchange event - }, document.title, value); - }; - - return LineHighlighter; - })(); -}).call(window); +window.LineHighlighter = LineHighlighter; diff --git a/app/assets/javascripts/repo/components/repo_preview.vue b/app/assets/javascripts/repo/components/repo_preview.vue index 2200754cbef..0d9d132f766 100644 --- a/app/assets/javascripts/repo/components/repo_preview.vue +++ b/app/assets/javascripts/repo/components/repo_preview.vue @@ -1,23 +1,27 @@ + diff --git a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js deleted file mode 100644 index 7c32a38fbe7..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js +++ /dev/null @@ -1,51 +0,0 @@ -/* eslint-disable no-param-reassign */ - -import Vue from 'vue'; -import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; - -const global = window.gl || (window.gl = {}); -global.cycleAnalytics = global.cycleAnalytics || {}; - -global.cycleAnalytics.StageCodeComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - components: { - userAvatarImage, - }, - template: ` -
-
- {{ stage.description }} - -
- -
- `, -}); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_code_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_code_component.vue new file mode 100644 index 00000000000..e4d62b649e5 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_code_component.vue @@ -0,0 +1,47 @@ + + diff --git a/app/assets/javascripts/cycle_analytics/components/stage_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_component.vue new file mode 100644 index 00000000000..ab730af8f5b --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_component.vue @@ -0,0 +1,53 @@ + + + diff --git a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js deleted file mode 100644 index 5f4a0ac8590..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js +++ /dev/null @@ -1,52 +0,0 @@ -/* eslint-disable no-param-reassign */ -import Vue from 'vue'; -import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; - -const global = window.gl || (window.gl = {}); -global.cycleAnalytics = global.cycleAnalytics || {}; - -global.cycleAnalytics.StageIssueComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - components: { - userAvatarImage, - }, - template: ` -
-
- {{ stage.description }} - -
- -
- `, -}); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js deleted file mode 100644 index 11fee5410d9..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js +++ /dev/null @@ -1,53 +0,0 @@ -/* eslint-disable no-param-reassign */ -import Vue from 'vue'; -import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; -import iconCommit from '../svg/icon_commit.svg'; - -const global = window.gl || (window.gl = {}); -global.cycleAnalytics = global.cycleAnalytics || {}; - -global.cycleAnalytics.StagePlanComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - components: { - userAvatarImage, - }, - data() { - return { iconCommit }; - }, - template: ` -
-
- {{ stage.description }} - -
- -
- `, -}); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.vue new file mode 100644 index 00000000000..152c086a606 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.vue @@ -0,0 +1,56 @@ + + + diff --git a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js deleted file mode 100644 index b7ba9360f70..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js +++ /dev/null @@ -1,52 +0,0 @@ -/* eslint-disable no-param-reassign */ -import Vue from 'vue'; -import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; - -const global = window.gl || (window.gl = {}); -global.cycleAnalytics = global.cycleAnalytics || {}; - -global.cycleAnalytics.StageProductionComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - components: { - userAvatarImage, - }, - template: ` -
-
- {{ stage.description }} - -
- -
- `, -}); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js deleted file mode 100644 index f41a0d0e4ff..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js +++ /dev/null @@ -1,62 +0,0 @@ -/* eslint-disable no-param-reassign */ -import Vue from 'vue'; -import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; - -const global = window.gl || (window.gl = {}); -global.cycleAnalytics = global.cycleAnalytics || {}; - -global.cycleAnalytics.StageReviewComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - components: { - userAvatarImage, - }, - template: ` -
-
- {{ stage.description }} - -
- -
- `, -}); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_review_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_review_component.vue new file mode 100644 index 00000000000..9e66b690404 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_review_component.vue @@ -0,0 +1,62 @@ + + diff --git a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js deleted file mode 100644 index d7c906c9d39..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js +++ /dev/null @@ -1,53 +0,0 @@ -/* eslint-disable no-param-reassign */ -import Vue from 'vue'; -import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; -import iconBranch from '../svg/icon_branch.svg'; - -const global = window.gl || (window.gl = {}); -global.cycleAnalytics = global.cycleAnalytics || {}; - -global.cycleAnalytics.StageStagingComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - data() { - return { iconBranch }; - }, - components: { - userAvatarImage, - }, - template: ` -
-
- {{ stage.description }} - -
- -
- `, -}); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.vue new file mode 100644 index 00000000000..2787b5ea47b --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.vue @@ -0,0 +1,55 @@ + + diff --git a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js b/app/assets/javascripts/cycle_analytics/components/stage_test_component.js deleted file mode 100644 index 78cc97eea0b..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable no-param-reassign */ -import Vue from 'vue'; -import iconBuildStatus from '../svg/icon_build_status.svg'; -import iconBranch from '../svg/icon_branch.svg'; - -const global = window.gl || (window.gl = {}); -global.cycleAnalytics = global.cycleAnalytics || {}; - -global.cycleAnalytics.StageTestComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - data() { - return { iconBuildStatus, iconBranch }; - }, - template: ` -
-
- {{ stage.description }} - -
- -
- `, -}); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_test_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_test_component.vue new file mode 100644 index 00000000000..9c3d39ce011 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_test_component.vue @@ -0,0 +1,54 @@ + + diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.js b/app/assets/javascripts/cycle_analytics/components/total_time_component.js deleted file mode 100644 index d5e6167b2a8..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/total_time_component.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable no-param-reassign */ - -import Vue from 'vue'; - -const global = window.gl || (window.gl = {}); -global.cycleAnalytics = global.cycleAnalytics || {}; - -global.cycleAnalytics.TotalTimeComponent = Vue.extend({ - props: { - time: Object, - }, - template: ` - - - - - `, -}); diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.vue b/app/assets/javascripts/cycle_analytics/components/total_time_component.vue new file mode 100644 index 00000000000..9941b997b3f --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/total_time_component.vue @@ -0,0 +1,29 @@ + + diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js index 5f1221c4c49..8002b0b23c9 100644 --- a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js +++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js @@ -3,15 +3,14 @@ import Vue from 'vue'; import Cookies from 'js-cookie'; import Translate from '../vue_shared/translate'; -import LimitWarningComponent from './components/limit_warning_component'; -import './components/stage_code_component'; -import './components/stage_issue_component'; -import './components/stage_plan_component'; -import './components/stage_production_component'; -import './components/stage_review_component'; -import './components/stage_staging_component'; -import './components/stage_test_component'; -import './components/total_time_component'; +import limitWarningComponent from './components/limit_warning_component.vue'; +import stageCodeComponent from './components/stage_code_component.vue'; +import stagePlanComponent from './components/stage_plan_component.vue'; +import stageComponent from './components/stage_component.vue'; +import stageReviewComponent from './components/stage_review_component.vue'; +import stageStagingComponent from './components/stage_staging_component.vue'; +import stageTestComponent from './components/stage_test_component.vue'; +import totalTime from './components/total_time_component.vue'; import CycleAnalyticsService from './cycle_analytics_service'; import CycleAnalyticsStore from './cycle_analytics_store'; @@ -47,13 +46,13 @@ $(() => { }, }, components: { - 'stage-issue-component': gl.cycleAnalytics.StageIssueComponent, - 'stage-plan-component': gl.cycleAnalytics.StagePlanComponent, - 'stage-code-component': gl.cycleAnalytics.StageCodeComponent, - 'stage-test-component': gl.cycleAnalytics.StageTestComponent, - 'stage-review-component': gl.cycleAnalytics.StageReviewComponent, - 'stage-staging-component': gl.cycleAnalytics.StageStagingComponent, - 'stage-production-component': gl.cycleAnalytics.StageProductionComponent, + 'stage-issue-component': stageComponent, + 'stage-plan-component': stagePlanComponent, + 'stage-code-component': stageCodeComponent, + 'stage-test-component': stageTestComponent, + 'stage-review-component': stageReviewComponent, + 'stage-staging-component': stageStagingComponent, + 'stage-production-component': stageComponent, }, created() { this.fetchCycleAnalyticsData(); @@ -136,6 +135,6 @@ $(() => { }); // Register global components - Vue.component('limit-warning', LimitWarningComponent); - Vue.component('total-time', gl.cycleAnalytics.TotalTimeComponent); + Vue.component('limit-warning', limitWarningComponent); + Vue.component('total-time', totalTime); }); diff --git a/spec/javascripts/cycle_analytics/limit_warning_component_spec.js b/spec/javascripts/cycle_analytics/limit_warning_component_spec.js index 2fb9eb0ca85..13e9fe00a00 100644 --- a/spec/javascripts/cycle_analytics/limit_warning_component_spec.js +++ b/spec/javascripts/cycle_analytics/limit_warning_component_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import Translate from '~/vue_shared/translate'; -import limitWarningComp from '~/cycle_analytics/components/limit_warning_component'; +import limitWarningComp from '~/cycle_analytics/components/limit_warning_component.vue'; Vue.use(Translate); From a019369409e38ee6cb36e5782cefd8c944b12e53 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 26 Sep 2017 10:49:53 +0200 Subject: [PATCH 092/263] Expose avatar_url when requesting list of projects from API with simple=true --- .../unreleased/dm-simple-project-avatar-url.yml | 5 +++++ lib/api/entities.rb | 11 ++++++----- spec/requests/api/environments_spec.rb | 1 + spec/requests/api/projects_spec.rb | 1 + spec/requests/api/v3/projects_spec.rb | 1 + 5 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/dm-simple-project-avatar-url.yml diff --git a/changelogs/unreleased/dm-simple-project-avatar-url.yml b/changelogs/unreleased/dm-simple-project-avatar-url.yml new file mode 100644 index 00000000000..e517345f5d2 --- /dev/null +++ b/changelogs/unreleased/dm-simple-project-avatar-url.yml @@ -0,0 +1,5 @@ +--- +title: Expose avatar_url when requesting list of projects from API with simple=true +merge_request: +author: +type: added diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 71253f72533..9776a9dd74b 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -89,6 +89,9 @@ module API expose :ssh_url_to_repo, :http_url_to_repo, :web_url expose :name, :name_with_namespace expose :path, :path_with_namespace + expose :avatar_url do |project, options| + project.avatar_url(only_path: false) + end expose :star_count, :forks_count expose :created_at, :last_activity_at end @@ -146,9 +149,7 @@ module API expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda { |project, options| project.forked? } expose :import_status expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] } - expose :avatar_url do |user, options| - user.avatar_url(only_path: false) - end + expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) } expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] } expose :public_builds, as: :public_jobs @@ -193,8 +194,8 @@ module API class Group < Grape::Entity expose :id, :name, :path, :description, :visibility expose :lfs_enabled?, as: :lfs_enabled - expose :avatar_url do |user, options| - user.avatar_url(only_path: false) + expose :avatar_url do |group, options| + group.avatar_url(only_path: false) end expose :web_url expose :request_access_enabled diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb index 2361809e0e1..f8cd529a06c 100644 --- a/spec/requests/api/environments_spec.rb +++ b/spec/requests/api/environments_spec.rb @@ -20,6 +20,7 @@ describe API::Environments do path path_with_namespace star_count forks_count created_at last_activity_at + avatar_url ) get api("/projects/#{project.id}/environments", user) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 508df990952..18f6f7df1fa 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -193,6 +193,7 @@ describe API::Projects do path path_with_namespace star_count forks_count created_at last_activity_at + avatar_url ) get api('/projects?simple=true', user) diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb index cae2c3118da..e5282c3311f 100644 --- a/spec/requests/api/v3/projects_spec.rb +++ b/spec/requests/api/v3/projects_spec.rb @@ -89,6 +89,7 @@ describe API::V3::Projects do path path_with_namespace star_count forks_count created_at last_activity_at + avatar_url ) get v3_api('/projects?simple=true', user) From 2e221b8117fb98fc64d1ffb98196c77d4e172aa4 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 26 Sep 2017 11:52:30 +0100 Subject: [PATCH 093/263] Fix sidebar mobile toggle button border --- app/assets/stylesheets/framework/new-nav.scss | 5 ----- app/assets/stylesheets/framework/new-sidebar.scss | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/framework/new-nav.scss b/app/assets/stylesheets/framework/new-nav.scss index c3badec59c9..d4b3fb238d5 100644 --- a/app/assets/stylesheets/framework/new-nav.scss +++ b/app/assets/stylesheets/framework/new-nav.scss @@ -317,11 +317,6 @@ header.navbar-gitlab-new { align-self: center; color: $gl-text-color-secondary; - @media (max-width: $screen-xs-max) { - padding-left: 17px; - border-left: 1px solid $gl-text-color-quaternary; - } - .avatar-tile { margin-right: 4px; border: 1px solid $border-color; diff --git a/app/assets/stylesheets/framework/new-sidebar.scss b/app/assets/stylesheets/framework/new-sidebar.scss index 9c404b7e542..3f1cb97aebc 100644 --- a/app/assets/stylesheets/framework/new-sidebar.scss +++ b/app/assets/stylesheets/framework/new-sidebar.scss @@ -461,6 +461,13 @@ $new-sidebar-collapsed-width: 50px; font-size: 18px; } } + + @media (max-width: $screen-xs-max) { + + .breadcrumbs-links { + padding-left: 17px; + border-left: 1px solid $gl-text-color-quaternary; + } + } } @media (max-width: $screen-xs-max) { From da15b38850d8d345a17862754285c34a2fbf08b6 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 13:00:29 +0200 Subject: [PATCH 094/263] Add specs for pipeline builder abilities validator --- app/services/ci/create_pipeline_service.rb | 3 -- .../pipeline/chain/validate/abilities_spec.rb | 49 +++++++++++++------ 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 0bf38776afc..af1784fe1dc 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -46,9 +46,6 @@ module Ci private - def process_pipeline_sequence - end - def commit @commit ||= project.commit(origin_sha || origin_ref) end diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb index 9e217102886..e6decde475a 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb @@ -1,22 +1,41 @@ require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do + set(:project) { create(:project, :repository) } + set(:user) { create(:user) } + + let(:pipeline) do + build_stubbed(:ci_pipeline, ref: ref, project: project) + end + + let(:command) do + double('command', project: project, current_user: user) + end + + let(:step) { described_class.new(pipeline, command) } + + let(:ref) { 'master' } + + context 'when users has no ability to run a pipeline' do + before do + step.perform! + end + + it 'adds an error about insufficient permissions' do + expect(pipeline.errors.to_a) + .to include /Insufficient permissions/ + end + + it 'breaks the pipeline builder chain' do + expect(step.break?).to eq true + end + end + + context 'when user has ability to create a pipeline' do + end + describe '#allowed_to_create?' do - let(:user) { create(:user) } - let(:project) { create(:project, :repository) } - let(:ref) { 'master' } - - let(:pipeline) do - build_stubbed(:ci_pipeline, ref: ref, project: project) - end - - let(:command) do - double('command', project: project, current_user: user) - end - - subject do - described_class.new(pipeline, command).allowed_to_create? - end + subject { step.allowed_to_create? } context 'when user is a developer' do before do From 1a8777c8d775b951384fbe4b8cf050b26b247d00 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 13:02:57 +0200 Subject: [PATCH 095/263] Fix coding style offenses in pipeline chain classes --- app/services/ci/create_pipeline_service.rb | 1 - lib/gitlab/ci/pipeline/chain/create.rb | 4 +--- lib/gitlab/ci/pipeline/chain/sequence.rb | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index af1784fe1dc..df5b32d97ca 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -28,7 +28,6 @@ module Ci project: project, current_user: current_user) - sequence = Gitlab::Ci::Pipeline::Chain::Sequence .new(pipeline, command, SEQUENCE) diff --git a/lib/gitlab/ci/pipeline/chain/create.rb b/lib/gitlab/ci/pipeline/chain/create.rb index 8bd658b3069..d5e17a123df 100644 --- a/lib/gitlab/ci/pipeline/chain/create.rb +++ b/lib/gitlab/ci/pipeline/chain/create.rb @@ -9,9 +9,7 @@ module Gitlab ::Ci::Pipeline.transaction do pipeline.save! - if @command.seeds_block - @command.seeds_block.call(pipeline) - end + @command.seeds_block&.call(pipeline) ::Ci::CreatePipelineStagesService .new(project, current_user) diff --git a/lib/gitlab/ci/pipeline/chain/sequence.rb b/lib/gitlab/ci/pipeline/chain/sequence.rb index e8d1ab36883..c80d583939c 100644 --- a/lib/gitlab/ci/pipeline/chain/sequence.rb +++ b/lib/gitlab/ci/pipeline/chain/sequence.rb @@ -13,7 +13,7 @@ module Gitlab end def build! - @sequence.each do |step| + @sequence.each do |step| step.perform! break if step.break? From f696b04cc88bd38395caf8ccb4003c28f38a9c47 Mon Sep 17 00:00:00 2001 From: Mehdi Lahmam Date: Sun, 13 Aug 2017 21:15:04 +0200 Subject: [PATCH 096/263] Expose last pipeline details in API response when getting a single commit Closes #35692. --- ...pipeline-details-in-api-for-single-commit.yml | 5 +++++ doc/api/commits.md | 6 ++++++ lib/api/entities.rb | 1 + .../api/schemas/public_api/v4/commit/detail.json | 11 +++++++++-- .../schemas/public_api/v4/pipeline/basic.json | 16 ++++++++++++++++ spec/requests/api/commits_spec.rb | 5 +++++ 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/expose-last-pipeline-details-in-api-for-single-commit.yml create mode 100644 spec/fixtures/api/schemas/public_api/v4/pipeline/basic.json diff --git a/changelogs/unreleased/expose-last-pipeline-details-in-api-for-single-commit.yml b/changelogs/unreleased/expose-last-pipeline-details-in-api-for-single-commit.yml new file mode 100644 index 00000000000..d16e052cd92 --- /dev/null +++ b/changelogs/unreleased/expose-last-pipeline-details-in-api-for-single-commit.yml @@ -0,0 +1,5 @@ +--- +title: Expose last pipeline details in API response when getting a single commit +merge_request: 13521 +author: Mehdi Lahmam (@mehlah) +type: added diff --git a/doc/api/commits.md b/doc/api/commits.md index 2a78553782f..5a4a8d888b3 100644 --- a/doc/api/commits.md +++ b/doc/api/commits.md @@ -181,6 +181,12 @@ Example response: "parent_ids": [ "ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba" ], + "last_pipeline" : { + "id": 8, + "ref": "master", + "sha": "2dc6aa325a317eda67812f05600bdf0fcdc70ab0" + "status": "created" + } "stats": { "additions": 15, "deletions": 10, diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 71253f72533..085d1edc0fc 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -234,6 +234,7 @@ module API class RepoCommitDetail < RepoCommit expose :stats, using: Entities::RepoCommitStats expose :status + expose :last_pipeline, using: 'API::Entities::PipelineBasic' end class RepoBranch < Grape::Entity diff --git a/spec/fixtures/api/schemas/public_api/v4/commit/detail.json b/spec/fixtures/api/schemas/public_api/v4/commit/detail.json index b7b2535c204..88a3cad62f6 100644 --- a/spec/fixtures/api/schemas/public_api/v4/commit/detail.json +++ b/spec/fixtures/api/schemas/public_api/v4/commit/detail.json @@ -5,11 +5,18 @@ { "required" : [ "stats", - "status" + "status", + "last_pipeline" ], "properties": { "stats": { "$ref": "../commit_stats.json" }, - "status": { "type": ["string", "null"] } + "status": { "type": ["string", "null"] }, + "last_pipeline": { + "oneOf": [ + { "type": "null" }, + { "$ref": "../pipeline/basic.json" } + ] + } } } ] diff --git a/spec/fixtures/api/schemas/public_api/v4/pipeline/basic.json b/spec/fixtures/api/schemas/public_api/v4/pipeline/basic.json new file mode 100644 index 00000000000..0d127dc5297 --- /dev/null +++ b/spec/fixtures/api/schemas/public_api/v4/pipeline/basic.json @@ -0,0 +1,16 @@ +{ + "type": "object", + "required" : [ + "id", + "sha", + "ref", + "status" + ], + "properties" : { + "id": { "type": "integer" }, + "sha": { "type": "string" }, + "ref": { "type": "string" }, + "status": { "type": "string" } + }, + "additionalProperties": false +} diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb index f663719d28c..94462b4572d 100644 --- a/spec/requests/api/commits_spec.rb +++ b/spec/requests/api/commits_spec.rb @@ -491,6 +491,7 @@ describe API::Commits do expect(json_response['stats']['deletions']).to eq(commit.stats.deletions) expect(json_response['stats']['total']).to eq(commit.stats.total) expect(json_response['status']).to be_nil + expect(json_response['last_pipeline']).to be_nil end context 'when ref does not exist' do @@ -573,6 +574,10 @@ describe API::Commits do expect(response).to have_http_status(200) expect(response).to match_response_schema('public_api/v4/commit/detail') expect(json_response['status']).to eq('created') + expect(json_response['last_pipeline']['id']).to eq(pipeline.id) + expect(json_response['last_pipeline']['ref']).to eq(pipeline.ref) + expect(json_response['last_pipeline']['sha']).to eq(pipeline.sha) + expect(json_response['last_pipeline']['status']).to eq(pipeline.status) end context 'when pipeline succeeds' do From 2432d5bd9ec49ce5a6287ee57ef701c740dff7f9 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 13:22:28 +0200 Subject: [PATCH 097/263] Add specs for builder chain step that skipps pipelines --- lib/gitlab/ci/pipeline/chain/skip.rb | 2 +- .../lib/gitlab/ci/pipeline/chain/skip_spec.rb | 85 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb diff --git a/lib/gitlab/ci/pipeline/chain/skip.rb b/lib/gitlab/ci/pipeline/chain/skip.rb index 3f86275ae15..9a72de87bab 100644 --- a/lib/gitlab/ci/pipeline/chain/skip.rb +++ b/lib/gitlab/ci/pipeline/chain/skip.rb @@ -24,7 +24,7 @@ module Gitlab def commit_message_skips_ci? return false unless @pipeline.git_commit_message - @skipped ||= @pipeline.git_commit_message =~ SKIP_PATTERN + @skipped ||= !!(@pipeline.git_commit_message =~ SKIP_PATTERN) end end end diff --git a/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb new file mode 100644 index 00000000000..32bd5de829b --- /dev/null +++ b/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb @@ -0,0 +1,85 @@ +require 'spec_helper' + +describe Gitlab::Ci::Pipeline::Chain::Skip do + set(:project) { create(:project) } + set(:user) { create(:user) } + set(:pipeline) { create(:ci_pipeline, project: project) } + + let(:command) do + double('command', project: project, + current_user: user, + ignore_skip_ci: false, + save_incompleted: true) + end + + let(:step) { described_class.new(pipeline, command) } + + context 'when pipeline has been skipped by a user' do + before do + allow(pipeline).to receive(:git_commit_message) + .and_return('commit message [ci skip]') + + step.perform! + end + + it 'should break the chain' do + expect(step.break?).to be true + end + + it 'skips the pipeline' do + expect(pipeline.reload).to be_skipped + end + end + + context 'when pipeline has not been skipped' do + before do + step.perform! + end + + it 'should not break the chain' do + expect(step.break?).to be false + end + + it 'should not skip a pipeline chain' do + expect(pipeline.reload).not_to be_skipped + end + end + + context 'when [ci skip] should be ignored' do + let(:command) do + double('command', project: project, + current_user: user, + ignore_skip_ci: true) + end + + it 'does not break the chain' do + step.perform! + + expect(step.break?).to be false + end + end + + context 'when pipeline should be skipped but not persisted' do + let(:command) do + double('command', project: project, + current_user: user, + ignore_skip_ci: false, + save_incompleted: false) + end + + before do + allow(pipeline).to receive(:git_commit_message) + .and_return('commit message [ci skip]') + + step.perform! + end + + it 'breaks the chain' do + expect(step.break?).to be true + end + + it 'does not skip pipeline' do + expect(pipeline.reload).not_to be_skipped + end + end +end From 652ecff91be036382ecac6059093bfae80522c81 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 13:34:53 +0200 Subject: [PATCH 098/263] Add specs for builder chain that persist a pipeline --- .../gitlab/ci/pipeline/chain/create_spec.rb | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 spec/lib/gitlab/ci/pipeline/chain/create_spec.rb diff --git a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb new file mode 100644 index 00000000000..f54e2326b06 --- /dev/null +++ b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb @@ -0,0 +1,66 @@ +require 'spec_helper' + +describe Gitlab::Ci::Pipeline::Chain::Create do + set(:project) { create(:project) } + set(:user) { create(:user) } + + let(:pipeline) do + build(:ci_pipeline_with_one_job, project: project, + ref: 'master') + end + + let(:command) do + double('command', project: project, + current_user: user, + seeds_block: nil) + end + + let(:step) { described_class.new(pipeline, command) } + + before do + step.perform! + end + + context 'when pipeline is ready to be saved' do + it 'saves a pipeline' do + expect(pipeline).to be_persisted + end + + it 'does not break the chain' do + expect(step.break?).to be false + end + + it 'creates stages' do + expect(pipeline.reload.stages).to be_one + end + end + + context 'when pipeline has validation errors' do + let(:pipeline) do + build(:ci_pipeline, project: project, ref: nil) + end + + it 'breaks the chain' do + expect(step.break?).to be true + end + + it 'appends validation error' do + expect(pipeline.errors.to_a) + .to include /Failed to persist the pipeline/ + end + end + + context 'when there is a seed block present' do + let(:seeds) { spy('pipeline seeds') } + + let(:command) do + double('command', project: project, + current_user: user, + seeds_block: seeds) + end + + it 'executes the block' do + expect(seeds).to have_received(:call).with(pipeline) + end + end +end From 39f05fd85ed53e2045f615a55baa3158f5eb20cc Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 13:40:37 +0200 Subject: [PATCH 099/263] Add specs for pipeline builder repository validator --- .../chain/validate/repository_spec.rb | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb new file mode 100644 index 00000000000..bb356efe9ad --- /dev/null +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper' + +describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do + set(:project) { create(:project, :repository) } + set(:user) { create(:user) } + + let(:command) do + double('command', project: project, current_user: user) + end + + let!(:step) { described_class.new(pipeline, command) } + + before do + step.perform! + end + + context 'when pipeline ref and sha exists' do + let(:pipeline) do + build_stubbed(:ci_pipeline, ref: 'master', sha: '123', project: project) + end + + it 'does not break the chain' do + expect(step.break?).to be false + end + + it 'does not append pipeline errors' do + expect(pipeline.errors).to be_empty + end + end + + context 'when pipeline ref does not exist' do + let(:pipeline) do + build_stubbed(:ci_pipeline, ref: 'something', project: project) + end + + it 'breaks the chain' do + expect(step.break?).to be true + end + + it 'adds an error about missing ref' do + expect(pipeline.errors.to_a) + .to include 'Reference not found' + end + end + + context 'when pipeline does not have SHA set' do + let(:pipeline) do + build_stubbed(:ci_pipeline, ref: 'master', sha: nil, project: project) + end + + it 'breaks the chain' do + expect(step.break?).to be true + end + + it 'adds an error about missing SHA' do + expect(pipeline.errors.to_a) + .to include 'Commit not found' + end + end +end From 6a9cfdde02b33b0a53d9f2b0f1bb3ee0e092a46d Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 14:04:28 +0200 Subject: [PATCH 100/263] Add specs for pipeline builder that validates config --- .../ci/pipeline/chain/validate/config_spec.rb | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb new file mode 100644 index 00000000000..d5e885b7409 --- /dev/null +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb @@ -0,0 +1,127 @@ +require 'spec_helper' + +describe Gitlab::Ci::Pipeline::Chain::Validate::Config do + set(:project) { create(:project) } + set(:user) { create(:user) } + + let(:command) do + double('command', project: project, + current_user: user, + save_incompleted: true) + end + + let!(:step) { described_class.new(pipeline, command) } + + before do + step.perform! + end + + context 'when pipeline has no YAML configuration' do + let(:pipeline) do + build_stubbed(:ci_pipeline, project: project) + end + + it 'appends errors about missing configuration' do + expect(pipeline.errors.to_a) + .to include 'Missing .gitlab-ci.yml file' + end + + it 'breaks the chain' do + expect(step.break?).to be true + end + end + + context 'when YAML configuration contains errors' do + let(:pipeline) do + build(:ci_pipeline, project: project, config: 'invalid YAML') + end + + it 'appends errors about YAML errors' do + expect(pipeline.errors.to_a) + .to include 'Invalid configuration format' + end + + it 'breaks the chain' do + expect(step.break?).to be true + end + + context 'when saving incomplete pipeline is allowed' do + let(:command) do + double('command', project: project, + current_user: user, + save_incompleted: true) + end + + it 'fails the pipeline' do + expect(pipeline.reload).to be_failed + end + end + + context 'when saving incomplete pipeline is not allowed' do + let(:command) do + double('command', project: project, + current_user: user, + save_incompleted: false) + end + + it 'does not drop pipeline' do + expect(pipeline).not_to be_failed + expect(pipeline).not_to be_persisted + end + end + end + + context 'when pipeline has no stages / jobs' do + let(:config) do + { rspec: { + script: 'ls', + only: ['something'] + } + } + end + + let(:pipeline) do + build(:ci_pipeline, project: project, config: config) + end + + it 'appends an error about missing stages' do + expect(pipeline.errors.to_a) + .to include 'No stages / jobs for this pipeline.' + end + + it 'breaks the chain' do + expect(step.break?).to be true + end + end + + context 'when pipeline contains configuration validation errors' do + let(:config) { { rspec: { } } } + + let(:pipeline) do + build(:ci_pipeline, project: project, config: config) + end + + it 'appends configuration validation errors to pipeline errors' do + expect(pipeline.errors.to_a) + .to include "jobs:rspec config can't be blank" + end + + it 'breaks the chain' do + expect(step.break?).to be true + end + end + + context 'when pipeline is correct and complete' do + let(:pipeline) do + build(:ci_pipeline_with_one_job, project: project) + end + + it 'does not invalidate the pipeline' do + expect(pipeline).to be_valid + end + + it 'does not break the chain' do + expect(step.break?).to be false + end + end +end From 53cad500433b69c77628ce020587fd5c9227690c Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 14:13:08 +0200 Subject: [PATCH 101/263] Add missing tests for pipeline chain access validator --- .../ci/pipeline/chain/validate/abilities_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb index e6decde475a..0bbdd23f4d6 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb @@ -32,6 +32,19 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do end context 'when user has ability to create a pipeline' do + before do + project.add_developer(user) + + step.perform! + end + + it 'does not invalidate the pipeline' do + expect(pipeline).to be_valid + end + + it 'does not break the chain' do + expect(step.break?).to eq false + end end describe '#allowed_to_create?' do From f6bd832f3fb5a833422c7a08deda844f6e78ab93 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 14:15:05 +0200 Subject: [PATCH 102/263] Fix some code style offenses in pipeline chain classes --- spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb index d5e885b7409..3740df88f42 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb @@ -76,8 +76,7 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do { rspec: { script: 'ls', only: ['something'] - } - } + } } end let(:pipeline) do @@ -95,7 +94,7 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do end context 'when pipeline contains configuration validation errors' do - let(:config) { { rspec: { } } } + let(:config) { { rspec: {} } } let(:pipeline) do build(:ci_pipeline, project: project, config: config) From 835bdcb88e3eff70b33d27b6ca42e7d1970eac35 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 26 Sep 2017 14:24:40 +0200 Subject: [PATCH 103/263] Add specs for pipeline chain builder sequence class --- .../gitlab/ci/pipeline/chain/sequence_spec.rb | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb diff --git a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb new file mode 100644 index 00000000000..e165e0fac2a --- /dev/null +++ b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' + +describe Gitlab::Ci::Pipeline::Chain::Sequence do + set(:project) { create(:project) } + set(:user) { create(:user) } + + let(:pipeline) { build_stubbed(:ci_pipeline) } + let(:command) { double('command' ) } + let(:first_step) { spy('first step') } + let(:second_step) { spy('second step') } + let(:sequence) { [first_step, second_step] } + + subject do + described_class.new(pipeline, command, sequence) + end + + context 'when one of steps breaks the chain' do + before do + allow(first_step).to receive(:break?).and_return(true) + end + + it 'does not process the second step' do + subject.build! do |pipeline, sequence| + expect(sequence).not_to be_complete + end + + expect(second_step).not_to have_received(:perform!) + end + + it 'returns a pipeline object' do + expect(subject.build!).to eq pipeline + end + end + + context 'when all chains are executed correctly' do + before do + sequence.each do |step| + allow(step).to receive(:break?).and_return(false) + end + end + + it 'iterates through entire sequence' do + subject.build! do |pipeline, sequence| + expect(sequence).to be_complete + end + + expect(first_step).to have_received(:perform!) + expect(second_step).to have_received(:perform!) + end + + it 'returns a pipeline object' do + expect(subject.build!).to eq pipeline + end + end +end From 0ed23790a43a0fd5001773937c66a06533f60c6c Mon Sep 17 00:00:00 2001 From: James Ramsay Date: Mon, 25 Sep 2017 16:02:08 -0400 Subject: [PATCH 104/263] Fix spelling of occurred --- app/assets/javascripts/blob/notebook/index.js | 4 ++-- app/assets/javascripts/blob/pdf/index.js | 4 ++-- app/assets/javascripts/boards/components/board_new_issue.js | 2 +- .../javascripts/environments/components/environment.vue | 2 +- .../environments/folder/environments_folder_view.vue | 2 +- app/assets/javascripts/filtered_search/dropdown_emoji.js | 2 +- app/assets/javascripts/filtered_search/dropdown_non_user.js | 2 +- app/assets/javascripts/filtered_search/dropdown_user.js | 2 +- .../javascripts/filtered_search/filtered_search_manager.js | 2 +- app/assets/javascripts/pipelines/mixins/pipelines.js | 2 +- .../javascripts/repo/components/repo_commit_section.vue | 2 +- app/assets/javascripts/repo/components/repo_preview.vue | 2 +- app/assets/javascripts/sidebar/lib/sidebar_move_issue.js | 4 ++-- app/assets/javascripts/sidebar/sidebar_mediator.js | 2 +- spec/features/issues/filtered_search/recent_searches_spec.rb | 2 +- spec/javascripts/blob/notebook/index_spec.js | 4 ++-- spec/javascripts/blob/pdf/index_spec.js | 2 +- 17 files changed, 21 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/blob/notebook/index.js b/app/assets/javascripts/blob/notebook/index.js index 27312d718b0..c858a6bb7b4 100644 --- a/app/assets/javascripts/blob/notebook/index.js +++ b/app/assets/javascripts/blob/notebook/index.js @@ -40,10 +40,10 @@ export default () => { class="text-center" v-if="error"> - An error occured whilst loading the file. Please try again later. + An error occurred whilst loading the file. Please try again later. - An error occured whilst parsing the file. + An error occurred whilst parsing the file.

diff --git a/app/assets/javascripts/blob/pdf/index.js b/app/assets/javascripts/blob/pdf/index.js index 0ed915c1ac9..7109f356540 100644 --- a/app/assets/javascripts/blob/pdf/index.js +++ b/app/assets/javascripts/blob/pdf/index.js @@ -48,10 +48,10 @@ export default () => { class="text-center" v-if="error"> - An error occured whilst loading the file. Please try again later. + An error occurred whilst loading the file. Please try again later. - An error occured whilst decoding the file. + An error occurred whilst decoding the file.

diff --git a/app/assets/javascripts/boards/components/board_new_issue.js b/app/assets/javascripts/boards/components/board_new_issue.js index 541b8049855..bc28f7f45f4 100644 --- a/app/assets/javascripts/boards/components/board_new_issue.js +++ b/app/assets/javascripts/boards/components/board_new_issue.js @@ -68,7 +68,7 @@ export default {
- An error occured. Please try again. + An error occurred. Please try again.