diff options
22 files changed, 274 insertions, 32 deletions
diff --git a/app/assets/javascripts/environments/components/empty_state.vue b/app/assets/javascripts/environments/components/empty_state.vue index 28d2dda9e43..2360a52645b 100644 --- a/app/assets/javascripts/environments/components/empty_state.vue +++ b/app/assets/javascripts/environments/components/empty_state.vue @@ -18,27 +18,28 @@ export default { }; </script> <template> - <div class="blank-state-row"> - <div class="blank-state-center"> - <h2 class="blank-state-title js-blank-state-title"> - {{ s__("Environments|You don't have any environments right now.") }} - </h2> + <div class="empty-state"> + <div class="text-content"> + <h4 class="blank-state-title js-blank-state-title"> + {{ s__("Environments|You don't have any environments right now") }} + </h4> <p class="blank-state-text"> {{ s__(`Environments|Environments are places where -code gets deployed, such as staging or production.`) }} - <br /> + code gets deployed, such as staging or production.`) }} <a :href="helpPath"> {{ s__("Environments|Read more about environments") }} </a> </p> - <a - v-if="canCreateEnvironment" - :href="newPath" - class="btn btn-success js-new-environment-button" - > - {{ s__("Environments|New environment") }} - </a> + <div class="text-center"> + <a + v-if="canCreateEnvironment" + :href="newPath" + class="btn btn-success js-new-environment-button" + > + {{ s__("Environments|New environment") }} + </a> + </div> </div> </div> </template> diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml index 3625224fbcd..174033f3d49 100644 --- a/app/views/layouts/nav/sidebar/_project.html.haml +++ b/app/views/layouts/nav/sidebar/_project.html.haml @@ -86,7 +86,7 @@ - if project_nav_tab? :issues = nav_link(controller: @project.issues_enabled? ? [:issues, :labels, :milestones, :boards] : :issues) do - = link_to project_issues_path(@project), class: 'shortcuts-issues' do + = link_to project_issues_path(@project), class: 'shortcuts-issues qa-issues-item' do .nav-icon-container = sprite_icon('issues') %span.nav-item-name @@ -115,7 +115,7 @@ = boards_link_text = nav_link(controller: :labels) do - = link_to project_labels_path(@project), title: _('Labels') do + = link_to project_labels_path(@project), title: _('Labels'), class: 'qa-labels-link' do %span = _('Labels') diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml index 11a05eada30..06ee883d6dc 100644 --- a/app/views/projects/labels/index.html.haml +++ b/app/views/projects/labels/index.html.haml @@ -8,7 +8,7 @@ - if can_admin_label - content_for(:header_content) do .nav-controls - = link_to _('New label'), new_project_label_path(@project), class: "btn btn-success" + = link_to _('New label'), new_project_label_path(@project), class: "btn btn-success qa-label-create-new" - if labels_or_filters #promote-label-modal diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml index 6eb1f8f0853..d5fb85ba0f3 100644 --- a/app/views/shared/issuable/_label_dropdown.html.haml +++ b/app/views/shared/issuable/_label_dropdown.html.haml @@ -20,7 +20,7 @@ = hidden_field_tag data_options[:field_name], use_id ? label.try(:id) : label.try(:title), id: nil .dropdown - %button.dropdown-menu-toggle.js-label-select.js-multiselect{ class: classes.join(' '), type: "button", data: dropdown_data } + %button.dropdown-menu-toggle.js-label-select.js-multiselect.qa-issuable-label{ class: classes.join(' '), type: "button", data: dropdown_data } - apply_is_default_styles = (selected.nil? || selected.empty?) && !no_default_styles %span.dropdown-toggle-text{ class: ("is-default" if apply_is_default_styles) } = multi_label_name(selected, label_name) diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index aa136af1955..10ffe8dd37f 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -98,7 +98,7 @@ = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') - if can_edit_issuable = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right' - .value.issuable-show-labels.dont-hide.hide-collapsed{ class: ("has-labels" if selected_labels.any?) } + .value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) } - if selected_labels.any? - selected_labels.each do |label| = link_to_label(label, subject: issuable.project, type: issuable.to_ability_name) diff --git a/app/views/shared/labels/_form.html.haml b/app/views/shared/labels/_form.html.haml index 335c34a4632..7619d0a2e9c 100644 --- a/app/views/shared/labels/_form.html.haml +++ b/app/views/shared/labels/_form.html.haml @@ -4,18 +4,18 @@ .form-group.row = f.label :title, class: 'col-form-label col-sm-2' .col-sm-10 - = f.text_field :title, class: "form-control", required: true, autofocus: true + = f.text_field :title, class: "form-control qa-label-title", required: true, autofocus: true .form-group.row = f.label :description, class: 'col-form-label col-sm-2' .col-sm-10 - = f.text_field :description, class: "form-control js-quick-submit" + = f.text_field :description, class: "form-control js-quick-submit qa-label-description" .form-group.row = f.label :color, "Background color", class: 'col-form-label col-sm-2' .col-sm-10 .input-group .input-group-prepend .input-group-text.label-color-preview - = f.text_field :color, class: "form-control" + = f.text_field :color, class: "form-control qa-label-color" .form-text.text-muted Choose any color. %br @@ -30,5 +30,5 @@ - if @label.persisted? = f.submit 'Save changes', class: 'btn btn-success js-save-button' - else - = f.submit 'Create label', class: 'btn btn-success js-save-button' + = f.submit 'Create label', class: 'btn btn-success js-save-button qa-label-create-button' = link_to 'Cancel', back_path, class: 'btn btn-cancel' diff --git a/changelogs/unreleased/gt-update-environments-empty-state.yml b/changelogs/unreleased/gt-update-environments-empty-state.yml new file mode 100644 index 00000000000..dcb477cdbe4 --- /dev/null +++ b/changelogs/unreleased/gt-update-environments-empty-state.yml @@ -0,0 +1,5 @@ +--- +title: Update environments empty state +merge_request: 22297 +author: George Tsiolis +type: other diff --git a/doc/administration/git_protocol.md b/doc/administration/git_protocol.md new file mode 100644 index 00000000000..6b82771baf9 --- /dev/null +++ b/doc/administration/git_protocol.md @@ -0,0 +1,97 @@ +--- +description: "Set and configure Git protocol v2" +--- + +# Configuring Git Protocol v2 + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/46555) in GitLab 11.4. + +--- + +Git protocol v2 improves the v1 wire protocol in several ways and is +enabled by default in GitLab for HTTP requests. In order to enable SSH, +further configuration is needed by the administrator. + +More details about the new features and improvements are available in +the [Google Open Source Blog](https://opensource.googleblog.com/2018/05/introducing-git-protocol-version-2.html) +and the [protocol documentation](https://github.com/git/git/blob/master/Documentation/technical/protocol-v2.txt). + +## Requirements + +From the client side, `git` `v2.18.0` or newer must be installed. + +From the server side, if we want to configure SSH we need to set the `sshd` +server to accept the `GIT_PROTOCOL` environment, + +``` +# /etc/ssh/sshd_config +AcceptEnv GIT_PROTOCOL +``` + +Once configured, restart the SSH daemon. In Ubuntu, run: + +```sh +sudo service ssh restart +``` + +## Instructions + +In order to use the new protocol, clients need to either pass the configuration +`-c protocol.version=2` to the git command, or set it globally: + +```sh +git config --global protocol.version 2 +``` + +### HTTP connections + +Verify Git v2 is used by the client: + +```sh +GIT_TRACE_CURL=1 git -c protocol.version=2 ls-remote https://your-gitlab-instance.com/group/repo.git 2>&1 | grep Git-Protocol +``` + +You should see that the `Git-Protocol` header is sent: + +``` +16:29:44.577888 http.c:657 => Send header: Git-Protocol: version=2 +``` + +Verify Git v2 is used by the server: + +```sh +GIT_TRACE_PACKET=1 git -c protocol.version=2 ls-remote https://your-gitlab-instance.com/group/repo.git 2>&1 | head +``` + +Example response using Git protocol v2: + +```sh +$ GIT_TRACE_PACKET=1 git -c protocol.version=2 ls-remote https://your-gitlab-instance.com/group/repo.git 2>&1 | head +10:42:50.574485 pkt-line.c:80 packet: git< # service=git-upload-pack +10:42:50.574653 pkt-line.c:80 packet: git< 0000 +10:42:50.574673 pkt-line.c:80 packet: git< version 2 +10:42:50.574679 pkt-line.c:80 packet: git< agent=git/2.18.1 +10:42:50.574684 pkt-line.c:80 packet: git< ls-refs +10:42:50.574688 pkt-line.c:80 packet: git< fetch=shallow +10:42:50.574693 pkt-line.c:80 packet: git< server-option +10:42:50.574697 pkt-line.c:80 packet: git< 0000 +10:42:50.574817 pkt-line.c:80 packet: git< version 2 +10:42:50.575308 pkt-line.c:80 packet: git< agent=git/2.18.1 +``` + +### SSH Connections + +Verify Git v2 is used by the client: + +```sh +GIT_SSH_COMMAND="ssh -v" git -c protocol.version=2 ls-remote ssh://your-gitlab-instance.com:group/repo.git 2>&1 |grep GIT_PROTOCOL +``` + +You should see that the `GIT_PROTOCOL` environment variable is sent: + +``` +debug1: Sending env GIT_PROTOCOL = version=2 +``` + +For the server side, you can use the [same examples from HTTP](#http-connections), changing the +URL to use SSH. diff --git a/doc/administration/index.md b/doc/administration/index.md index 8e6fa9563c7..6083806af6c 100644 --- a/doc/administration/index.md +++ b/doc/administration/index.md @@ -130,6 +130,7 @@ created in snippets, wikis, and repos. - [Custom Git hooks](custom_hooks.md): Custom Git hooks (on the filesystem) for when webhooks aren't enough. - [Git LFS configuration](../workflow/lfs/lfs_administration.md): Learn how to configure LFS for GitLab. - [Housekeeping](housekeeping.md): Keep your Git repositories tidy and fast. +- [Configuring Git Protocol v2](git_protocol.md): Git protocol version 2 support. ## Monitoring GitLab diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e7aa7ee1347..46be1df6503 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2600,7 +2600,7 @@ msgstr "" msgid "Environments|Updated" msgstr "" -msgid "Environments|You don't have any environments right now." +msgid "Environments|You don't have any environments right now" msgstr "" msgid "Epic" @@ -45,6 +45,7 @@ module QA autoload :Group, 'qa/factory/resource/group' autoload :Issue, 'qa/factory/resource/issue' autoload :Project, 'qa/factory/resource/project' + autoload :Label, 'qa/factory/resource/label' autoload :MergeRequest, 'qa/factory/resource/merge_request' autoload :ProjectImportedFromGithub, 'qa/factory/resource/project_imported_from_github' autoload :MergeRequestFromFork, 'qa/factory/resource/merge_request_from_fork' @@ -240,6 +241,11 @@ module QA autoload :Banner, 'qa/page/layout/banner' end + module Label + autoload :New, 'qa/page/label/new' + autoload :Index, 'qa/page/label/index' + end + module MergeRequest autoload :New, 'qa/page/merge_request/new' autoload :Show, 'qa/page/merge_request/show' diff --git a/qa/qa/factory/resource/label.rb b/qa/qa/factory/resource/label.rb new file mode 100644 index 00000000000..4080f15bf66 --- /dev/null +++ b/qa/qa/factory/resource/label.rb @@ -0,0 +1,39 @@ +require 'securerandom' + +module QA + module Factory + module Resource + class Label < Factory::Base + attr_accessor :title, + :description, + :color + + product(:title) { |factory| factory.title } + + dependency Factory::Resource::Project, as: :project do |project| + project.name = 'project-with-label' + end + + def initialize + @title = "qa-test-#{SecureRandom.hex(8)}" + @description = 'This is a test label' + @color = '#0033CC' + end + + def fabricate! + project.visit! + + Page::Project::Menu.act { go_to_labels } + Page::Label::Index.act { go_to_new_label } + + Page::Label::New.perform do |page| + page.fill_title(@title) + page.fill_description(@description) + page.fill_color(@color) + page.create_label + end + end + end + end + end +end diff --git a/qa/qa/factory/resource/merge_request.rb b/qa/qa/factory/resource/merge_request.rb index ddb62bd0a68..c4620348202 100644 --- a/qa/qa/factory/resource/merge_request.rb +++ b/qa/qa/factory/resource/merge_request.rb @@ -56,6 +56,10 @@ module QA page.fill_title(@title) page.fill_description(@description) page.choose_milestone(@milestone) if @milestone + labels.each do |label| + page.select_label(label) + end + page.create_merge_request end end diff --git a/qa/qa/page/label/index.rb b/qa/qa/page/label/index.rb new file mode 100644 index 00000000000..323acd57743 --- /dev/null +++ b/qa/qa/page/label/index.rb @@ -0,0 +1,15 @@ +module QA + module Page + module Label + class Index < Page::Base + view 'app/views/projects/labels/index.html.haml' do + element :label_create_new + end + + def go_to_new_label + click_element :label_create_new + end + end + end + end +end diff --git a/qa/qa/page/label/new.rb b/qa/qa/page/label/new.rb new file mode 100644 index 00000000000..b5422dc9400 --- /dev/null +++ b/qa/qa/page/label/new.rb @@ -0,0 +1,30 @@ +module QA + module Page + module Label + class New < Page::Base + view 'app/views/shared/labels/_form.html.haml' do + element :label_title + element :label_description + element :label_color + element :label_create_button + end + + def create_label + click_element :label_create_button + end + + def fill_title(title) + fill_element :label_title, title + end + + def fill_description(description) + fill_element :label_description, description + end + + def fill_color(color) + fill_element :label_color, color + end + end + end + end +end diff --git a/qa/qa/page/merge_request/new.rb b/qa/qa/page/merge_request/new.rb index 83cc4bbbace..1f8f1fbca8e 100644 --- a/qa/qa/page/merge_request/new.rb +++ b/qa/qa/page/merge_request/new.rb @@ -22,6 +22,10 @@ module QA element :issuable_dropdown_menu_milestone end + view 'app/views/shared/issuable/_label_dropdown.html.haml' do + element :issuable_label + end + def create_merge_request click_element :issuable_create_button end @@ -40,6 +44,12 @@ module QA click_on milestone.title end end + + def select_label(label) + click_element :issuable_label + + click_link label.title + end end end end diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index b40e90ef4ad..376606afb5d 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -23,6 +23,10 @@ module QA element :squash_checkbox end + view 'app/views/shared/issuable/_sidebar.html.haml' do + element :labels_block + end + def fast_forward_possible? !has_text?('Fast-forward merge is not possible') end @@ -64,6 +68,13 @@ module QA end end + def has_label?(label) + page.within(element_selector_css(:labels_block)) do + element = find('span', text: label) + !element.nil? + end + end + def merge! # The merge button is disabled on load wait do diff --git a/qa/qa/page/project/menu.rb b/qa/qa/page/project/menu.rb index b32d5ea772b..bc125d1af88 100644 --- a/qa/qa/page/project/menu.rb +++ b/qa/qa/page/project/menu.rb @@ -22,6 +22,7 @@ module QA element :activity_link, "title: _('Activity')" # rubocop:disable QA/ElementWithPattern element :wiki_link_text, "Wiki" # rubocop:disable QA/ElementWithPattern element :milestones_link + element :labels_link end view 'app/assets/javascripts/fly_out_nav.js' do @@ -104,8 +105,20 @@ module QA end end + def go_to_labels + hover_issues { click_element :labels_link } + end + private + def hover_issues + within_sidebar do + find_element(:issues_item).hover + + yield + end + end + def hover_settings within_sidebar do find('.qa-settings-item').hover diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb index bcf55a02a61..f59bfb6b64d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb @@ -16,16 +16,26 @@ module QA milestone.project = current_project end + new_label = Factory::Resource::Label.fabricate! do |label| + label.project = current_project + label.title = 'qa-mr-test-label' + label.description = 'Merge Request label' + end + Factory::Resource::MergeRequest.fabricate! do |merge_request| merge_request.title = 'This is a merge request with a milestone' merge_request.description = 'Great feature with milestone' merge_request.project = current_project merge_request.milestone = current_milestone + merge_request.labels.push(new_label) end - expect(page).to have_content('This is a merge request with a milestone') - expect(page).to have_content('Great feature with milestone') - expect(page).to have_content(/Opened [\w\s]+ ago/) + Page::MergeRequest::Show.perform do |merge_request| + expect(merge_request).to have_content('This is a merge request with a milestone') + expect(merge_request).to have_content('Great feature with milestone') + expect(merge_request).to have_content(/Opened [\w\s]+ ago/) + expect(merge_request).to have_label(new_label.title) + end Page::Issuable::Sidebar.perform do |sidebar| expect(sidebar).to have_milestone(current_milestone.title) diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index f0890018286..917ba495f01 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -95,7 +95,7 @@ describe 'Environments page', :js do end it 'does not show environments and counters are set to zero' do - expect(page).to have_content('You don\'t have any environments right now.') + expect(page).to have_content('You don\'t have any environments right now') expect(page.find('.js-environments-tab-available .badge').text).to eq('0') expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0') diff --git a/spec/javascripts/environments/emtpy_state_spec.js b/spec/javascripts/environments/emtpy_state_spec.js index 10a19af4175..d71dfe8197e 100644 --- a/spec/javascripts/environments/emtpy_state_spec.js +++ b/spec/javascripts/environments/emtpy_state_spec.js @@ -27,7 +27,7 @@ describe('environments empty state', () => { it('renders empty state and new environment button', () => { expect( vm.$el.querySelector('.js-blank-state-title').textContent.trim(), - ).toEqual('You don\'t have any environments right now.'); + ).toEqual('You don\'t have any environments right now'); expect( vm.$el.querySelector('.js-new-environment-button').getAttribute('href'), @@ -47,7 +47,7 @@ describe('environments empty state', () => { it('renders empty state without new button', () => { expect( vm.$el.querySelector('.js-blank-state-title').textContent.trim(), - ).toEqual('You don\'t have any environments right now.'); + ).toEqual('You don\'t have any environments right now'); expect( vm.$el.querySelector('.js-new-environment-button'), diff --git a/spec/javascripts/environments/environments_app_spec.js b/spec/javascripts/environments/environments_app_spec.js index 1be983f3592..7edc0ccac0b 100644 --- a/spec/javascripts/environments/environments_app_spec.js +++ b/spec/javascripts/environments/environments_app_spec.js @@ -50,7 +50,7 @@ describe('Environment', () => { expect( component.$el.querySelector('.js-blank-state-title').textContent, - ).toContain('You don\'t have any environments right now.'); + ).toContain('You don\'t have any environments right now'); }); }); @@ -127,7 +127,7 @@ describe('Environment', () => { it('should render empty state', () => { expect( component.$el.querySelector('.js-blank-state-title').textContent, - ).toContain('You don\'t have any environments right now.'); + ).toContain('You don\'t have any environments right now'); }); }); |