diff options
31 files changed, 225 insertions, 101 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c055d1f384e..7ed09fb1db8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ entry. - Show correct environment log in admin/logs (@duk3luk3 !7191) - Fix Milestone dropdown not stay selected for `Upcoming` and `No Milestone` option !7117 +- Diff collapse won't shift when collapsing. - Backups do not fail anymore when using tar on annex and custom_hooks only. !5814 - Adds user project membership expired event to clarify why user was removed (Callum Dryden) - Trim leading and trailing whitespace on project_path (Linus Thiel) @@ -13,6 +14,7 @@ entry. - Adds support for the `token` attribute in project hooks API (Gauvain Pocentek) - Adds an optional path parameter to the Commits API to filter commits by path (Luis HGO) - Fix Markdown styling inside reference links (Jan Zdráhal) +- Create new issue board list after creating a new label - Fix extra space on Build sidebar on Firefox !7060 - Fail gracefully when creating merge request with non-existing branch (alexsanford) - Fix mobile layout issues in admin user overview page !7087 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index 7ada0d303f3..3eefcb9dd5b 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -0.8.5 +1.0.0 diff --git a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 b/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 index fe1a6dc7ea0..14f618fd5d5 100644 --- a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 +++ b/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 @@ -2,6 +2,19 @@ $(() => { const Store = gl.issueBoards.BoardsStore; + $(document).off('created.label').on('created.label', (e, label) => { + Store.new({ + title: label.title, + position: Store.state.lists.length - 2, + list_type: 'label', + label: { + id: label.id, + title: label.title, + color: label.color + } + }); + }); + $('.js-new-board-list').each(function () { const $this = $(this); new gl.CreateLabelDropdown($this.closest('.dropdown').find('.dropdown-new-label'), $this.data('namespace-path'), $this.data('project-path')); diff --git a/app/assets/javascripts/create_label.js.es6 b/app/assets/javascripts/create_label.js.es6 index f20580b1279..744aa0afa03 100644 --- a/app/assets/javascripts/create_label.js.es6 +++ b/app/assets/javascripts/create_label.js.es6 @@ -115,6 +115,8 @@ .show(); } else { this.$dropdownBack.trigger('click'); + + $(document).trigger('created.label', label); } }); } diff --git a/app/assets/javascripts/extensions/element.js.es6 b/app/assets/javascripts/extensions/element.js.es6 index c74fc9ad074..afb2f0d6956 100644 --- a/app/assets/javascripts/extensions/element.js.es6 +++ b/app/assets/javascripts/extensions/element.js.es6 @@ -1,5 +1,7 @@ -/* eslint-disable */ -Element.prototype.matches = Element.prototype.matches || Element.prototype.msMatches; +/* global Element */ +/* eslint-disable consistent-return, max-len */ + +Element.prototype.matches = Element.prototype.matches || Element.prototype.msMatchesSelector; Element.prototype.closest = function closest(selector, selectedElement = this) { if (!selectedElement) return; diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index ce117c3fba5..202ed5ae8fe 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -4,7 +4,7 @@ margin-right: $margin-right; } -.avatar-container { +.avatar-circle { float: left; margin-right: 15px; border-radius: $avatar_radius; @@ -27,7 +27,7 @@ } .avatar { - @extend .avatar-container; + @extend .avatar-circle; width: 40px; height: 40px; padding: 0; @@ -64,8 +64,8 @@ &.s160 { font-size: 96px; line-height: 158px; } } -.image-container { - @extend .avatar-container; +.avatar-container { + @extend .avatar-circle; overflow: hidden; display: flex; @@ -76,4 +76,4 @@ margin: 0; align-self: center; } -}
\ No newline at end of file +} diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss index 8ecf7fcb96d..47d3e72679b 100644 --- a/app/assets/stylesheets/pages/commit.scss +++ b/app/assets/stylesheets/pages/commit.scss @@ -36,9 +36,42 @@ padding: 10px 0; margin-bottom: 0; - .commit-options-dropdown-caret { - @media (max-width: $screen-sm) { - margin-left: 0; + @media (min-width: $screen-sm-min) { + display: flex; + align-items: center; + + .commit-meta { + flex: 1; + } + } + + .commit-hash-full { + @media (max-width: $screen-sm-max) { + width: 80px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + vertical-align: bottom; + } + } + + .commit-action-buttons { + i { + color: $gl-icon-color; + font-size: 13px; + margin-right: 3px; + } + + @media (max-width: $screen-xs-max) { + .dropdown { + width: 100%; + margin-top: 10px; + } + + .dropdown-toggle { + width: 100%; + } } } } @@ -188,17 +221,6 @@ } } -.commit-action-buttons { - position: relative; - top: -1px; - - i { - color: $gl-icon-color; - font-size: 13px; - margin-right: 3px; - } -} - /* * Commit message textarea for web editor and * custom merge request message diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb index 0a493b7a12b..2dbe0075465 100644 --- a/app/models/project_services/jira_service.rb +++ b/app/models/project_services/jira_service.rb @@ -163,6 +163,21 @@ class JiraService < IssueTrackerService add_comment(data, issue_key) end + # reason why service cannot be tested + def disabled_title + "Please fill in Password and Username." + end + + def can_test? + username.present? && password.present? + end + + # JIRA does not need test data. + # We are requesting the project that belongs to the project key. + def test_data(user = nil, project = nil) + nil + end + def test_settings return unless url.present? # Test settings by getting the project diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml index 05c88ca1cc8..664bb417c6a 100644 --- a/app/views/admin/groups/_group.html.haml +++ b/app/views/admin/groups/_group.html.haml @@ -16,7 +16,7 @@ %span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)} = visibility_level_icon(group.visibility_level, fw: false) - .image-container.s40 + .avatar-container.s40 = image_tag group_icon(group), class: "avatar s40 hidden-xs" .title = link_to [:admin, group], class: 'group-name' do diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index a7c1a4f5038..40871e32913 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -13,7 +13,7 @@ Group info: %ul.well-list %li - .image-container.s60 + .avatar-container.s60 = image_tag group_icon(@group), class: "avatar s60" %li %span.light Name: diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index 10dce6f3d8f..b37b8d4fee7 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -76,7 +76,7 @@ .title = link_to [:admin, project.namespace.becomes(Namespace), project] do .dash-project-avatar - .image-container.s40 + .avatar-container.s40 = project_icon(project, alt: '', class: 'avatar project-avatar s40') %span.project-full-name %span.namespace-name diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 2f90c19d4b4..2706e8692d1 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -8,7 +8,7 @@ .form-group .col-sm-offset-2.col-sm-10 - .image-container.s160 + .avatar-container.s160 = image_tag group_icon(@group), alt: '', class: 'avatar group-avatar s160' %p.light - if @group.avatar? diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 275581b3af8..b439b40a75a 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -6,7 +6,7 @@ .cover-block.groups-cover-block %div{ class: container_class } - .image-container.s70.group-avatar + .avatar-container.s70.group-avatar = image_tag group_icon(@group), class: "avatar s70 avatar-tile" .group-info .cover-title diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index e67b66d1fff..5a04c3318cf 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -1,7 +1,7 @@ - empty_repo = @project.empty_repo? .project-home-panel.text-center{ class: ("empty-project" if empty_repo) } %div{ class: container_class } - .image-container.s70.project-avatar + .avatar-container.s70.project-avatar = project_icon(@project, alt: @project.name, class: 'avatar s70 avatar-tile') %h1.project-title = @project.name diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index d8c95376b94..0ebc38d16cf 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -1,25 +1,25 @@ .commit-info-row.commit-info-row-header - %span.hidden-xs.hidden-sm Commit - = link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace js-details-short" - = link_to("#", class: "js-details-expand hidden-xs hidden-sm") do - %span.text-expander - \... - %span.js-details-content.hide - = link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace hidden-xs hidden-sm" - = clipboard_button(clipboard_text: @commit.id) - %span.hidden-xs authored - #{time_ago_with_tooltip(@commit.authored_date)} - %span by - = author_avatar(@commit, size: 24) - %strong - = commit_author_link(@commit, avatar: true, size: 24) - - if @commit.different_committer? - %span.light Committed by + .commit-meta + %strong Commit + %strong.monospace.js-details-short= @commit.short_id + = link_to("#", class: "js-details-expand hidden-xs hidden-sm") do + %span.text-expander + \... + %span.js-details-content.hide + %strong.monospace.commit-hash-full= @commit.id + = clipboard_button(clipboard_text: @commit.id) + %span.hidden-xs authored + #{time_ago_with_tooltip(@commit.authored_date)} + %span by + = author_avatar(@commit, size: 24) %strong - = commit_committer_link(@commit, avatar: true, size: 24) - #{time_ago_with_tooltip(@commit.committed_date)} - - .pull-right.commit-action-buttons + = commit_author_link(@commit, avatar: true, size: 24) + - if @commit.different_committer? + %span.light Committed by + %strong + = commit_committer_link(@commit, avatar: true, size: 24) + #{time_ago_with_tooltip(@commit.committed_date)} + .commit-action-buttons - if defined?(@notes_count) && @notes_count > 0 %span.btn.disabled.btn-grouped.hidden-xs.append-right-10 = icon('comment') @@ -28,8 +28,8 @@ Browse Files .dropdown.inline %a.btn.btn-default.dropdown-toggle{ data: { toggle: "dropdown" } } - %span.hidden-xs Options - = icon('caret-down', class: ".commit-options-dropdown-caret") + %span Options + = icon('caret-down') %ul.dropdown-menu.dropdown-menu-align-right %li.visible-xs-block.visible-sm-block = link_to namespace_project_tree_path(@project.namespace, @project, @commit) do diff --git a/app/views/projects/diffs/_file_header.html.haml b/app/views/projects/diffs/_file_header.html.haml index 73993f35b39..d3ed8e1bf38 100644 --- a/app/views/projects/diffs/_file_header.html.haml +++ b/app/views/projects/diffs/_file_header.html.haml @@ -1,4 +1,4 @@ -%i.fa.diff-toggle-caret +%i.fa.diff-toggle-caret.fa-fw - if defined?(blob) && blob && diff_file.submodule? %span = icon('archive fw') diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index a5422966617..0aa8801c2d8 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -118,7 +118,7 @@ Project avatar .form-group - if @project.avatar? - .image-container.s160 + .avatar-container.s160 = project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160') %p.light - if @project.avatar_in_git diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml index 752fbc21a11..b41edeb2c7e 100644 --- a/app/views/projects/services/_form.html.haml +++ b/app/views/projects/services/_form.html.haml @@ -12,6 +12,9 @@ = form.submit 'Save changes', class: 'btn btn-save' - if @service.valid? && @service.activated? - - disabled = @service.can_test? ? '':'disabled' - = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled}", title: @service.disabled_title + - unless @service.can_test? + - disabled_class = 'disabled' + - disabled_title = @service.disabled_title + + = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled_class}", title: disabled_title = link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel" diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml index 562291a61df..19221e3391f 100644 --- a/app/views/shared/groups/_group.html.haml +++ b/app/views/shared/groups/_group.html.haml @@ -24,7 +24,7 @@ %span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)} = visibility_level_icon(group.visibility_level, fw: false) - .image-container.s40 + .avatar-container.s40 = image_tag group_icon(group), class: "avatar s40 hidden-xs" .title = link_to group, class: 'group-name' do diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 3d2122a159c..264391fe84f 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -32,7 +32,7 @@ = link_to project_path(project), class: dom_class(project) do - if avatar .dash-project-avatar - .image-container.s40 + .avatar-container.s40 - if use_creator_avatar = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:'' - else diff --git a/app/views/users/_groups.html.haml b/app/views/users/_groups.html.haml index 78f253f9023..eff6c80d144 100644 --- a/app/views/users/_groups.html.haml +++ b/app/views/users/_groups.html.haml @@ -1,5 +1,5 @@ .clearfix - groups.each do |group| = link_to group, class: 'profile-groups-avatars inline', title: group.name do - .image-container.s40 + .avatar-container.s40 = image_tag group_icon(group), class: 'avatar group-avatar s40' diff --git a/changelogs/unreleased/issue_23032.yml b/changelogs/unreleased/issue_23032.yml new file mode 100644 index 00000000000..d376cf52112 --- /dev/null +++ b/changelogs/unreleased/issue_23032.yml @@ -0,0 +1,4 @@ +--- +title: Allow to test JIRA service settings without having a repository +merge_request: +author: diff --git a/doc/install/installation.md b/doc/install/installation.md index 7e947e4b2ba..b5e2640b380 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -403,7 +403,7 @@ If you are not using Linux you may have to run `gmake` instead of cd /home/git sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-workhorse.git cd gitlab-workhorse - sudo -u git -H git checkout v0.8.5 + sudo -u git -H git checkout v1.0.0 sudo -u git -H make ### Initialize Database and Activate Advanced Features diff --git a/doc/update/8.13-to-8.14.md b/doc/update/8.13-to-8.14.md index 787511fd6cf..46ea19d11d0 100644 --- a/doc/update/8.13-to-8.14.md +++ b/doc/update/8.13-to-8.14.md @@ -84,7 +84,7 @@ GitLab 8.1. ```bash cd /home/git/gitlab-workhorse sudo -u git -H git fetch --all -sudo -u git -H git checkout v0.8.5 +sudo -u git -H git checkout v1.0.0 sudo -u git -H make ``` diff --git a/features/snippets/public_snippets.feature b/features/snippets/public_snippets.feature deleted file mode 100644 index c2afb63b6d8..00000000000 --- a/features/snippets/public_snippets.feature +++ /dev/null @@ -1,10 +0,0 @@ -Feature: Public snippets - Scenario: Unauthenticated user should see public snippets - Given There is public "Personal snippet one" snippet - And I visit snippet page "Personal snippet one" - Then I should see snippet "Personal snippet one" - - Scenario: Unauthenticated user should see raw public snippets - Given There is public "Personal snippet one" snippet - And I visit snippet raw page "Personal snippet one" - Then I should see raw snippet "Personal snippet one" diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb index 4df4e89f5b9..35b71599708 100644 --- a/features/steps/shared/diff_note.rb +++ b/features/steps/shared/diff_note.rb @@ -210,7 +210,7 @@ module SharedDiffNote end step 'I click side-by-side diff button' do - find('#parallel-diff-btn').click + find('#parallel-diff-btn').trigger('click') end step 'I see side-by-side diff button' do diff --git a/features/steps/snippets/public_snippets.rb b/features/steps/snippets/public_snippets.rb deleted file mode 100644 index 2ebdca5ed30..00000000000 --- a/features/steps/snippets/public_snippets.rb +++ /dev/null @@ -1,25 +0,0 @@ -class Spinach::Features::PublicSnippets < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedSnippet - - step 'I should see snippet "Personal snippet one"' do - expect(page).to have_no_xpath("//i[@class='public-snippet']") - end - - step 'I should see raw snippet "Personal snippet one"' do - expect(page).to have_text(snippet.content) - end - - step 'I visit snippet page "Personal snippet one"' do - visit snippet_path(snippet) - end - - step 'I visit snippet raw page "Personal snippet one"' do - visit raw_snippet_path(snippet) - end - - def snippet - @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") - end -end diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index a92075fec8f..6cb8753e8fc 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -380,6 +380,25 @@ describe 'Issue Boards', feature: true, js: true do wait_for_board_cards(1, 5) end + + it 'creates new list from a new label' do + click_button 'Create new list' + + wait_for_ajax + + click_link 'Create new label' + + fill_in('new_label_name', with: 'Testing New Label') + + first('.suggest-colors a').click + + click_button 'Create' + + wait_for_ajax + wait_for_vue_resource + + expect(page).to have_selector('.board', count: 5) + end end end diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb index b3ba40b35af..472491188c9 100644 --- a/spec/features/projects/ref_switcher_spec.rb +++ b/spec/features/projects/ref_switcher_spec.rb @@ -22,8 +22,20 @@ feature 'Ref switcher', feature: true, js: true do input.native.send_keys :down input.native.send_keys :down input.native.send_keys :enter + end + + expect(page).to have_title 'expand-collapse-files' + end + + it "user selects ref with special characters" do + click_button 'master' + wait_for_ajax - expect(page).to have_content 'expand-collapse-files' + page.within '.project-refs-form' do + page.fill_in 'Search branches and tags', with: "'test'" + click_link "'test'" end + + expect(page).to have_title "'test'" end end diff --git a/spec/features/snippets/public_snippets_spec.rb b/spec/features/snippets/public_snippets_spec.rb new file mode 100644 index 00000000000..34300ccb940 --- /dev/null +++ b/spec/features/snippets/public_snippets_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +feature 'Public Snippets', feature: true do + scenario 'Unauthenticated user should see public snippets' do + public_snippet = create(:personal_snippet, :public) + + visit snippet_path(public_snippet) + + expect(page).to have_content(public_snippet.content) + end + + scenario 'Unauthenticated user should see raw public snippets' do + public_snippet = create(:personal_snippet, :public) + + visit raw_snippet_path(public_snippet) + + expect(page).to have_content(public_snippet.content) + end +end diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb index ee0e38bd373..05ee4a08391 100644 --- a/spec/models/project_services/jira_service_spec.rb +++ b/spec/models/project_services/jira_service_spec.rb @@ -33,6 +33,41 @@ describe JiraService, models: true do end end + describe '#can_test?' do + let(:jira_service) { described_class.new } + + it 'returns false if username is blank' do + allow(jira_service).to receive_messages( + url: 'http://jira.example.com', + username: '', + password: '12345678' + ) + + expect(jira_service.can_test?).to be_falsy + end + + it 'returns false if password is blank' do + allow(jira_service).to receive_messages( + url: 'http://jira.example.com', + username: 'tester', + password: '' + ) + + expect(jira_service.can_test?).to be_falsy + end + + it 'returns true if password and username are present' do + jira_service = described_class.new + allow(jira_service).to receive_messages( + url: 'http://jira.example.com', + username: 'tester', + password: '12345678' + ) + + expect(jira_service.can_test?).to be_truthy + end + end + describe "Execute" do let(:user) { create(:user) } let(:project) { create(:project) } @@ -46,16 +81,19 @@ describe JiraService, models: true do service_hook: true, url: 'http://jira.example.com', username: 'gitlab_jira_username', - password: 'gitlab_jira_password' + password: 'gitlab_jira_password', + project_key: 'GitLabProject' ) @jira_service.save - project_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123' - @transitions_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123/transitions' - @comment_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123/comment' + project_issues_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123' + @project_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/project/GitLabProject' + @transitions_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123/transitions' + @comment_url = 'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/issue/JIRA-123/comment' - WebMock.stub_request(:get, project_url) + WebMock.stub_request(:get, @project_url) + WebMock.stub_request(:get, project_issues_url) WebMock.stub_request(:post, @transitions_url) WebMock.stub_request(:post, @comment_url) end @@ -99,6 +137,14 @@ describe JiraService, models: true do body: /this-is-a-custom-id/ ).once end + + context "when testing" do + it "tries to get jira project" do + @jira_service.execute(nil) + + expect(WebMock).to have_requested(:get, @project_url) + end + end end describe "Stored password invalidation" do |