Commit c8c2bab5 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-05-31

# Conflicts:
#	app/controllers/profiles_controller.rb
#	app/controllers/projects/issues_controller.rb
#	app/views/projects/issues/_nav_btns.html.haml
#	app/views/shared/issuable/form/_merge_params.html.haml
#	config/routes/project.rb
#	db/schema.rb
#	locale/gitlab.pot
#	spec/controllers/application_controller_spec.rb

[ci skip]
parents 409abd54 c0bac47d
...@@ -126,7 +126,6 @@ export default { ...@@ -126,7 +126,6 @@ export default {
</div> </div>
<form <form
v-if="!isCompact" v-if="!isCompact"
class="form-horizontal"
@submit.prevent.stop="commitChanges" @submit.prevent.stop="commitChanges"
ref="formEl" ref="formEl"
> >
......
...@@ -59,7 +59,7 @@ export default { ...@@ -59,7 +59,7 @@ export default {
ref="form" ref="form"
:action="deleteWikiUrl" :action="deleteWikiUrl"
method="post" method="post"
class="form-horizontal js-requires-input" class="js-requires-input"
> >
<input <input
ref="method" ref="method"
......
...@@ -79,12 +79,13 @@ export default { ...@@ -79,12 +79,13 @@ export default {
}; };
</script> </script>
<template> <template>
<div class="ci-job-dropdown-container dropdown"> <div class="ci-job-dropdown-container dropdown dropright">
<button <button
v-tooltip v-tooltip
type="button" type="button"
data-toggle="dropdown" data-toggle="dropdown"
data-container="body" data-container="body"
data-boundary="viewport"
class="dropdown-menu-toggle build-content" class="dropdown-menu-toggle build-content"
:title="tooltipText" :title="tooltipText"
> >
......
...@@ -87,7 +87,8 @@ table { ...@@ -87,7 +87,8 @@ table {
display: none; display: none;
} }
.dropdown-toggle::after { .dropdown-toggle::after,
.dropright .dropdown-menu-toggle::after {
// Remove bootstrap's dropdown caret // Remove bootstrap's dropdown caret
display: none; display: none;
} }
...@@ -148,8 +149,14 @@ table { ...@@ -148,8 +149,14 @@ table {
} }
} }
.nav-tabs .nav-link { .nav-tabs {
border: 0; .nav-link {
border: 0;
}
.nav-item {
margin-bottom: 0;
}
} }
pre code { pre code {
......
/*
* This is a minimal stylesheet, meant to be used for error pages.
*/
@import 'framework/variables';
@import '../../../node_modules/bootstrap/scss/functions';
@import '../../../node_modules/bootstrap/scss/variables';
@import '../../../node_modules/bootstrap/scss/mixins';
@import '../../../node_modules/bootstrap/scss/reboot';
@import '../../../node_modules/bootstrap/scss/buttons';
@import '../../../node_modules/bootstrap/scss/forms';
$body-color: #666;
$header-color: #456;
body {
color: $body-color;
text-align: center;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
font-size: 14px;
}
h1 {
font-size: 56px;
line-height: 100px;
font-weight: 400;
color: $header-color;
}
h2 {
font-size: 24px;
color: $body-color;
line-height: 1.5em;
}
h3 {
color: $header-color;
font-size: 20px;
font-weight: 400;
line-height: 28px;
}
img {
max-width: 80vw;
display: block;
margin: 40px auto;
}
a {
text-decoration: none;
color: $blue-600;
}
.page-container {
margin: auto 20px;
}
.container {
margin: auto;
max-width: 600px;
border-bottom: 1px solid $border-color;
padding-bottom: 1em;
}
.action-container {
padding: 0.5em 0;
}
.form-inline-flex {
display: flex;
flex-wrap: wrap;
button {
display: block;
width: 100%;
}
.field {
display: block;
width: 100%;
margin-bottom: 1em;
}
@include media-breakpoint-up(sm) {
flex-wrap: nowrap;
button {
width: auto;
}
.field {
margin-bottom: 0;
margin-right: 0.5em;
}
}
}
.error-nav {
padding: 0;
text-align: center;
li {
display: block;
padding-bottom: 1em;
}
@include media-breakpoint-up(sm) {
li {
display: inline-block;
padding-bottom: 0;
&:not(:first-child)::before {
content: '\00B7';
display: inline-block;
padding: 0 1em;
}
}
}
}
...@@ -169,11 +169,14 @@ ...@@ -169,11 +169,14 @@
color: $color-800; color: $color-800;
} }
.nav-links li a.active { .nav-links li {
border-bottom: 2px solid $color-500; &.active a,
a.active {
border-bottom: 2px solid $color-500;
.badge.badge-pill { .badge.badge-pill {
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
}
} }
} }
......
...@@ -31,14 +31,15 @@ ...@@ -31,14 +31,15 @@
color: $black; color: $black;
} }
} }
}
&.active { &.active a,
color: $black; a.active {
font-weight: $gl-font-weight-bold; color: $black;
font-weight: $gl-font-weight-bold;
.badge.badge-pill { .badge.badge-pill {
color: $black; color: $black;
}
} }
} }
} }
......
...@@ -382,6 +382,7 @@ $dropdown-chevron-size: 10px; ...@@ -382,6 +382,7 @@ $dropdown-chevron-size: 10px;
$dropdown-toggle-active-border-color: darken($border-color, 14%); $dropdown-toggle-active-border-color: darken($border-color, 14%);
$dropdown-item-hover-bg: $gray-darker; $dropdown-item-hover-bg: $gray-darker;
$dropdown-fade-mask-height: 32px; $dropdown-fade-mask-height: 32px;
$dropdown-member-form-control-width: 163px;
/* /*
* Filtered Search * Filtered Search
......
...@@ -42,13 +42,12 @@ ...@@ -42,13 +42,12 @@
} }
} }
.form-horizontal { .form-group {
margin-top: 20px; margin-bottom: 0;
@include media-breakpoint-up(sm) { @include media-breakpoint-down(sm) {
display: -webkit-flex; display: block;
display: flex; margin-left: 5px;
margin-top: 3px;
} }
} }
...@@ -68,10 +67,15 @@ ...@@ -68,10 +67,15 @@
} }
.member-form-control { .member-form-control {
@include media-breakpoint-down(xs) { @include media-breakpoint-down(sm) {
padding-bottom: 5px; width: $dropdown-member-form-control-width;
margin-left: 0; margin-left: 0;
padding-bottom: 5px;
}
@include media-breakpoint-down(xs) {
margin-right: 0; margin-right: 0;
width: auto;
} }
} }
...@@ -257,10 +261,6 @@ ...@@ -257,10 +261,6 @@
align-self: flex-start; align-self: flex-start;
} }
.form-horizontal ~ .btn {
margin-right: 0;
}
@include media-breakpoint-down(xs) { @include media-breakpoint-down(xs) {
display: block; display: block;
...@@ -270,6 +270,12 @@ ...@@ -270,6 +270,12 @@
display: block; display: block;
} }
.controls > .btn:last-child {
margin-left: 5px;
margin-right: 5px;
width: auto;
}
.form-control { .form-control {
width: 100%; width: 100%;
} }
...@@ -282,10 +288,6 @@ ...@@ -282,10 +288,6 @@
.member-controls { .member-controls {
margin-top: 5px; margin-top: 5px;
} }
.form-horizontal {
margin-top: 10px;
}
} }
} }
...@@ -309,10 +311,6 @@ ...@@ -309,10 +311,6 @@
margin-top: 0; margin-top: 0;
} }
.form-horizontal {
display: block;
}
.member-form-control { .member-form-control {
margin: 5px 0; margin: 5px 0;
} }
......
...@@ -154,14 +154,15 @@ class ApplicationController < ActionController::Base ...@@ -154,14 +154,15 @@ class ApplicationController < ActionController::Base
end end
def render_403 def render_403
head :forbidden respond_to do |format|
format.any { head :forbidden }
format.html { render "errors/access_denied", layout: "errors", status: 403 }
end
end end
def render_404 def render_404
respond_to do |format| respond_to do |format|
format.html do format.html { render "errors/not_found", layout: "errors", status: 404 }
render file: Rails.root.join("public", "404"), layout: false, status: "404"
end
# Prevent the Rails CSRF protector from thinking a missing .js file is a JavaScript file # Prevent the Rails CSRF protector from thinking a missing .js file is a JavaScript file
format.js { render json: '', status: :not_found, content_type: 'application/json' } format.js { render json: '', status: :not_found, content_type: 'application/json' }
format.any { head :not_found } format.any { head :not_found }
......
...@@ -39,7 +39,11 @@ class ProfilesController < Profiles::ApplicationController ...@@ -39,7 +39,11 @@ class ProfilesController < Profiles::ApplicationController
user.reset_feed_token! user.reset_feed_token!
end end
<<<<<<< HEAD
flash[:notice] = "Feed token was successfully reset" flash[:notice] = "Feed token was successfully reset"
=======
flash[:notice] = 'Feed token was successfully reset'
>>>>>>> upstream/master
redirect_to profile_personal_access_tokens_path redirect_to profile_personal_access_tokens_path
end end
......
...@@ -11,8 +11,12 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -11,8 +11,12 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :whitelist_query_limiting_ee, only: [:update] before_action :whitelist_query_limiting_ee, only: [:update]
before_action :whitelist_query_limiting, only: [:create, :create_merge_request, :move, :bulk_update] before_action :whitelist_query_limiting, only: [:create, :create_merge_request, :move, :bulk_update]
before_action :check_issues_available! before_action :check_issues_available!
<<<<<<< HEAD
before_action :issue, except: [:index, :calendar, :new, :create, :bulk_update, :export_csv] before_action :issue, except: [:index, :calendar, :new, :create, :bulk_update, :export_csv]
=======
before_action :issue, except: [:index, :calendar, :new, :create, :bulk_update]
>>>>>>> upstream/master
before_action :set_issuables_index, only: [:index, :calendar] before_action :set_issuables_index, only: [:index, :calendar]
# Allow write(create) issue # Allow write(create) issue
......
...@@ -100,8 +100,6 @@ module Issuable ...@@ -100,8 +100,6 @@ module Issuable
strip_attributes :title strip_attributes :title
after_save :ensure_metrics, unless: :imported?
# We want to use optimistic lock for cases when only title or description are involved # We want to use optimistic lock for cases when only title or description are involved
# http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html # http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
def locking_enabled? def locking_enabled?
......
...@@ -69,6 +69,7 @@ class Issue < ActiveRecord::Base ...@@ -69,6 +69,7 @@ class Issue < ActiveRecord::Base
scope :public_only, -> { where(confidential: false) } scope :public_only, -> { where(confidential: false) }
after_save :expire_etag_cache after_save :expire_etag_cache
after_save :ensure_metrics, unless: :imported?
attr_spammable :title, spam_title: true attr_spammable :title, spam_title: true
attr_spammable :description, spam_description: true attr_spammable :description, spam_description: true
......
...@@ -62,6 +62,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -62,6 +62,7 @@ class MergeRequest < ActiveRecord::Base
after_create :ensure_merge_request_diff, unless: :importing? after_create :ensure_merge_request_diff, unless: :importing?
after_update :clear_memoized_shas after_update :clear_memoized_shas
after_update :reload_diff_if_branch_changed after_update :reload_diff_if_branch_changed
after_save :ensure_metrics
# When this attribute is true some MR validation is ignored # When this attribute is true some MR validation is ignored
# It allows us to close or modify broken merge requests # It allows us to close or modify broken merge requests
......
class CommitStatusPresenter < Gitlab::View::Presenter::Delegated class CommitStatusPresenter < Gitlab::View::Presenter::Delegated
CALLOUT_FAILURE_MESSAGES = { CALLOUT_FAILURE_MESSAGES = {
unknown_failure: 'There is an unknown failure, please try again', unknown_failure: 'There is an unknown failure, please try again',
script_failure: 'There has been a script failure. Check the job log for more information',
api_failure: 'There has been an API failure, please try again', api_failure: 'There has been an API failure, please try again',
stuck_or_timeout_failure: 'There has been a timeout failure or the job got stuck. Check your timeout limits or try again', stuck_or_timeout_failure: 'There has been a timeout failure or the job got stuck. Check your timeout limits or try again',
runner_system_failure: 'There has been a runner system failure, please try again', runner_system_failure: 'There has been a runner system failure, please try again',
missing_dependency_failure: 'There has been a missing dependency failure, check the job log for more information' missing_dependency_failure: 'There has been a missing dependency failure'
}.freeze }.freeze
presents :build presents :build
......
...@@ -26,7 +26,7 @@ class JobEntity < Grape::Entity ...@@ -26,7 +26,7 @@ class JobEntity < Grape::Entity
expose :created_at expose :created_at
expose :updated_at expose :updated_at
expose :detailed_status, as: :status, with: StatusEntity expose :detailed_status, as: :status, with: StatusEntity
expose :callout_message, if: -> (*) { failed? } expose :callout_message, if: -> (*) { failed? && !build.script_failure? }
expose :recoverable, if: -> (*) { failed? } expose :recoverable, if: -> (*) { failed? }
private private
......
= form_for @application_setting, url: admin_application_settings_path, html: { class: 'form-horizontal fieldset-form' } do |f| = form_for @application_setting, url: admin_application_settings_path do |f|
= form_errors(@application_setting) = form_errors(@application_setting)
%fieldset %fieldset
.form-group .form-group.row
= f.label :mirror_available, 'Enable mirror configuration', class: 'control-label col-sm-2' = f.label :mirror_available, 'Enable mirror configuration', class: 'control-label col-sm-4'
.col-sm-10 .col-sm-8
.form-check .form-check
= f.check_box :mirror_available, class: 'form-check-input' = f.check_box :mirror_available, class: 'form-check-input'
= f.label :mirror_available, class: 'form-check-label' do = f.label :mirror_available, class: 'form-check-label' do
......
= form_for @application_setting, url: admin_application_settings_path, html: { class: 'form-horizontal fieldset-form' } do |f| = form_for @application_setting, url: admin_application_settings_path do |f|
= form_errors(@application_setting) = form_errors(@application_setting)
%fieldset %fieldset
.form-group .form-group.row
.col-sm-12 .col-sm-12
.form-check .form-check
= f.check_box :enforce_terms, class: 'form-check-input' = f.check_box :enforce_terms, class: 'form-check-input'
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= _("Require all users to accept Terms of Service when they access GitLab.") = _("Require all users to accept Terms of Service when they access GitLab.")
.form-text.text-muted .form-text.text-muted
= _("When enabled, users cannot use GitLab until the terms have been accepted.") = _("When enabled, users cannot use GitLab until the terms have been accepted.")
.form-group .form-group.row
.col-sm-12 .col-sm-12
= f.label :terms do = f.label :terms do
= _("Terms of Service Agreement") = _("Terms of Service Agreement")
......
= form_for [:admin, @application], url: @url, html: {role: 'form'} do |f| = form_for [:admin, @application], url: @url, html: {role: 'form'} do |f|
= form_errors(application) = form_errors(application)
= content_tag :div, class: 'form-group' do = content_tag :div, class: 'form-group row' do
= f.label :name, class: 'col-sm-2 col-form-label' = f.label :name, class: 'col-sm-2 col-form-label'
.col-sm-10 .col-sm-10
= f.text_field :name, class: 'form-control' = f.text_field :name, class: 'form-control'
= doorkeeper_errors_for application, :name = doorkeeper_errors_for application, :name
= content_tag :div, class: 'form-group' do = content_tag :div, class: 'form-group row' do
= f.label :redirect_uri, class: 'col-sm-2 col-form-label' = f.label :redirect_uri, class: 'col-sm-2 col-form-label'
.col-sm-10 .col-sm-10
= f.text_area :redirect_uri, class: 'form-control' = f.text_area :redirect_uri, class: 'form-control'
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
%code= Doorkeeper.configuration.native_redirect_uri %code= Doorkeeper.configuration.native_redirect_uri
for local tests for local tests
= content_tag :div, class: 'form-group' do = content_tag :div, class: 'form-group row' do
= f.label :trusted, class: 'col-sm-2 col-form-label' = f.label :trusted, class: 'col-sm-2 col-form-label'
.col-sm-10 .col-sm-10
= f.check_box :trusted = f.check_box :trusted
......
%nav
%ul.error-nav
%li
= link_to s_('Nav|Home'), root_path
%li
- if current_user
= link_to s_('Nav|Sign out and sign in with a different account'), destroy_user_session_path
- else
= link_to s_('Nav|Sign In / Register'), new_session_path(:user, redirect_to_referer: 'yes')
%li
= link_to s_('Nav|Help'), help_path
- message = local_assigns.fetch(:message) - message = local_assigns.fetch(:message)
- content_for(:title, 'Access Denied') - content_for(:title, 'Access Denied')
%img{ :alt => "GitLab Logo", :src => image_path('logo.svg') }
%h1 = image_tag('illustrations/error-403.svg', alt: '403', lazy: false)
403
.container .container
%h3 Access Denied %h3
%hr = s_("403|You don't have the permission to access this page.")
- if message - if message
%p %p
= message = message
- else %p
%p You are not allowed to access this page. = s_('403|Please contact your GitLab administrator to get the permission.')
%p Read more about project permissions #{link_to "here", help_page_path("user/permissions"), class: "vlink"} .action-container.js-go-back{ style: 'display: none' }
%a{ href: 'javascript:history.back()', class: 'btn btn-success' }
= s_('Go Back')
= render "errors/footer"
- content_for(:title, 'Not Found') - content_for(:title, 'Not Found')
%img{ :alt => "GitLab Logo", :src => image_path('logo.svg') } = image_tag('illustrations/error-404.svg', alt: '404', lazy: false)
%h1
404
.container .container
%h3 The resource you were looking for doesn't exist. %h3
%hr = s_('404|Page Not Found')
%p You may have mistyped the address or the page may have moved. %p
= s_("404|Make sure the address is correct and the page hasn't moved.")
%p
= s_('404|Please contact your GitLab administrator if you think this is a mistake.')
.action-container
= form_tag search_path, method: :get, class: 'form-inline-flex' do |f|
.field
= search_field_tag :search, '', placeholder: _('Search for projects, issues, etc.'), class: 'form-control'
= button_tag 'Search', class: 'btn btn-success', name: nil, type: 'submit'
= render 'errors/footer'
...@@ -3,57 +3,17 @@ ...@@ -3,57 +3,17 @@
%head %head
%meta{ :content => "width=device-width, initial-scale=1, maximum-scale=1", :name => "viewport" } %meta{ :content => "width=device-width, initial-scale=1, maximum-scale=1", :name => "viewport" }
%title= yield(:title) %title= yield(:title)
:css %style
body { = Rails.application.assets_manifest.find_sources('errors.css').first.to_s.html_safe
color: #666; %body
text-align: center; .page-container
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; = yield
margin: auto; -# haml-lint:disable InlineJavaScript
font-size: 14px; :javascript
} (function(){
var goBackElement = document.querySelector('.js-go-back');
h1 { if (goBackElement && history.length > 1) {
font-size: 56px; goBackElement.style.display = 'block';
line-height: 100px; }
font-weight: 400; }());
color: #456;
}
h2 {
font-size: 24px;
color: #666;
line-height: 1.5em;
}
h3 {
color: #456;
font-size: 20px;
font-weight: 400;
line-height: 28px;
}
hr {
max-width: 800px;
margin: 18px auto;
border: 0;
border-top: 1px solid #EEE;
border-bottom: 1px solid white;
}
img {
max-width: 40vw;
display: block;
margin: 40px auto;
}
.container {
margin: auto 20px;
}
ul {
margin: auto;
text-align: left;
display:inline-block;
}
%body
= yield
<<<<<<< HEAD
- show_rss_button = local_assigns.fetch(:show_rss_button, true) - show_rss_button = local_assigns.fetch(:show_rss_button, true)
- show_export_button = local_assigns.fetch(:show_export_button, true) - show_export_button = local_assigns.fetch(:show_export_button, true)
...@@ -9,6 +10,9 @@ ...@@ -9,6 +10,9 @@
- if show_export_button - if show_export_button
= render 'projects/issues/export_issues/button' = render 'projects/issues/export_issues/button'
=======
= render 'shared/issuable/feed_buttons'
>>>>>>> upstream/master
- if @can_bulk_update - if @can_bulk_update
= button_tag "Edit issues", class: "btn btn-default append-right-10 js-bulk-update-toggle" = button_tag "Edit issues", class: "btn btn-default append-right-10 js-bulk-update-toggle"
......
...@@ -12,8 +12,13 @@ ...@@ -12,8 +12,13 @@
= label_tag 'merge_request[force_remove_source_branch]', class: 'form-check-label' do = label_tag 'merge_request[force_remove_source_branch]', class: 'form-check-label' do
Remove source branch when merge request is accepted. Remove source branch when merge request is accepted.
<<<<<<< HEAD
.form-group .form-group
.col-sm-10.col-sm-offset-2 .col-sm-10.col-sm-offset-2
=======
.form-group.row
.col-sm-10.offset-sm-2
>>>>>>> upstream/master
.form-check .form-check
= hidden_field_tag 'merge_request[squash]', '0', id: nil = hidden_field_tag 'merge_request[squash]', '0', id: nil
= check_box_tag 'merge_request[squash]', '1', issuable.squash, class: 'form-check-input' = check_box_tag 'merge_request[squash]', '1', issuable.squash, class: 'form-check-input'
......
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
title: 'Resend invite' title: 'Resend invite'
- if user != current_user && member.can_update? - if user != current_user && member.can_update?
= form_for member, remote: true, html: { class: 'js-edit-member-form form-horizontal' } do |f| = form_for member, remote: true, html: { class: 'js-edit-member-form form-group row append-right-5' } do |f|
= f.hidden_field :access_level = f.hidden_field :access_level
.member-form-control.dropdown.append-right-5 .member-form-control.dropdown.append-right-5
%button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button", %button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button",
......
...@@ -5,25 +5,25 @@ ...@@ -5,25 +5,25 @@
.fade-right= icon('angle-right') .fade-right= icon('angle-right')
%ul.nav-links.scrolling-tabs.js-milestone-tabs.nav.nav-tabs %ul.nav-links.scrolling-tabs.js-milestone-tabs.nav.nav-tabs
- if issues_accessible - if issues_accessible
%li.active %li.nav-item
= link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do = link_to '#tab-issues', class: 'nav-link active', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do
Issues Issues
%span.badge.badge-pill= milestone.issues_visible_to_user(current_user).size %span.badge.badge-pill= milestone.issues_visible_to_user(current_user).size
%li %li.nav-item
= link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do = link_to '#tab-merge-requests', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do
Merge Requests Merge Requests
%span.badge.badge-pill= milestone.merge_requests.size %span.badge.badge-pill= milestone.merge_requests.size
- else - else
%li.active %li.nav-item
= link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do = link_to '#tab-merge-requests', class: 'nav-link active', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do
Merge Requests Merge Requests
%span.badge.badge-pill= milestone.merge_requests.size %span.badge.badge-pill= milestone.merge_requests.size
%li %li.nav-item
= link_to '#tab-participants', 'data-toggle' => 'tab', 'data-endpoint': milestone_participants_tab_path(milestone) do = link_to '#tab-participants', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_participants_tab_path(milestone) do
Participants Participants
%span.badge.badge-pill= milestone.participants.count %span.badge.badge-pill= milestone.participants.count
%li %li.nav-item
= link_to '#tab-labels', 'data-toggle' => 'tab', 'data-endpoint': milestone_labels_tab_path(milestone) do = link_to '#tab-labels', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_labels_tab_path(milestone) do
Labels Labels
%span.badge.badge-pill= milestone.labels.count %span.badge.badge-pill= milestone.labels.count
......
---
title: Update 404 and 403 pages with helpful actions.
merge_request: 19096
author:
type: changed
---
title: Take two for MR metrics population background migration
merge_request: 19097
author:
type: other
---
title: Removes redundant script failure message from Job page
merge_request: 19138
author:
type: changed
---
title: Add merge requests list endpoint for groups
merge_request:
author:
type: other
---
title: Make ActiveRecordSubscriber rails 5 compatible
merge_request:
author:
type: other
---
title: Eliminate cached N+1 queries for projects in Issue API
merge_request:
author:
type: performance
...@@ -130,6 +130,7 @@ module Gitlab ...@@ -130,6 +130,7 @@ module Gitlab
config.assets.precompile << "snippets.css" config.assets.precompile << "snippets.css"
config.assets.precompile << "locale/**/app.js" config.assets.precompile << "locale/**/app.js"
config.assets.precompile << "emoji_sprites.css" config.assets.precompile << "emoji_sprites.css"
config.assets.precompile << "errors.css"
# Import gitlab-svgs directly from vendored directory # Import gitlab-svgs directly from vendored directory
config.assets.paths << "#{config.root}/node_modules/@gitlab-org/gitlab-svgs/dist" config.assets.paths << "#{config.root}/node_modules/@gitlab-org/gitlab-svgs/dist"
......
...@@ -386,9 +386,12 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -386,9 +386,12 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end end
end end
<<<<<<< HEAD
## EE-specific ## EE-specific
resources :vulnerability_feedback, only: [:index, :create, :destroy], constraints: { id: /\d+/ } resources :vulnerability_feedback, only: [:index, :create, :destroy], constraints: { id: /\d+/ }
=======
>>>>>>> upstream/master
get :issues, to: 'issues#calendar', constraints: lambda { |req| req.format == :ics } get :issues, to: 'issues#calendar', constraints: lambda { |req| req.format == :ics }
resources :issues, concerns: :awardable, constraints: { id: /\d+/ } do resources :issues, concerns: :awardable, constraints: { id: /\d+/ } do
member do member do
......
class MigrateRemainingMrMetricsPopulatingBackgroundMigration < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
BATCH_SIZE = 5_000
MIGRATION = 'PopulateMergeRequestMetricsWithEventsData'
DELAY_INTERVAL = 10.minutes
disable_ddl_transaction!
class MergeRequest < ActiveRecord::Base
self.table_name = 'merge_requests'
include ::EachBatch
end
def up
# Perform any ongoing background migration that might still be running. This
# avoids scheduling way too many of the same jobs on self-hosted instances
# if they're updating GitLab across multiple versions. The "Take one"
# migration was executed on 10.4 on
# SchedulePopulateMergeRequestMetricsWithEventsData.
Gitlab::BackgroundMigration.steal(MIGRATION)
metrics_not_exists_clause = <<~SQL
NOT EXISTS (SELECT 1 FROM merge_request_metrics
WHERE merge_request_metrics.merge_request_id = merge_requests.id)
SQL
relation = MergeRequest.where(metrics_not_exists_clause)
# We currently have ~400_000 MR records without metrics on GitLab.com.
# This means it'll schedule ~80 jobs (5000 MRs each) with a 10 minutes gap,
# so this should take ~14 hours for all background migrations to complete.
#
queue_background_migration_jobs_by_range_at_intervals(relation,
MIGRATION,
DELAY_INTERVAL,
batch_size: BATCH_SIZE)
end
def down
end
end
...@@ -2657,10 +2657,13 @@ ActiveRecord::Schema.define(version: 20180529093006) do ...@@ -2657,10 +2657,13 @@ ActiveRecord::Schema.define(version: 20180529093006) do
t.boolean "notified_of_own_activity" t.boolean "notified_of_own_activity"
t.boolean "support_bot" t.boolean "support_bot"
t.string "preferred_language" t.string "preferred_language"
<<<<<<< HEAD
t.boolean "email_opted_in" t.boolean "email_opted_in"
t.string "email_opted_in_ip" t.string "email_opted_in_ip"
t.integer "email_opted_in_source_id" t.integer "email_opted_in_source_id"
t.datetime "email_opted_in_at" t.datetime "email_opted_in_at"
=======
>>>>>>> upstream/master
t.integer "theme_id", limit: 2 t.integer "theme_id", limit: 2
t.integer "accepted_term_id" t.integer "accepted_term_id"
t.string "feed_token" t.string "feed_token"
......
...@@ -241,6 +241,112 @@ Parameters: ...@@ -241,6 +241,112 @@ Parameters:
] ]
``` ```
## List group merge requests
Get all merge requests for this group and its subgroups.
The `state` parameter can be used to get only merge requests with a given state (`opened`, `closed`, or `merged`) or all of them (`all`).
The pagination parameters `page` and `per_page` can be used to restrict the list of merge requests.
```
GET /groups/:id/merge_requests
GET /groups/:id/merge_requests?state=opened
GET /groups/:id/merge_requests?state=all
GET /groups/:id/merge_requests?milestone=release
GET /groups/:id/merge_requests?labels=bug,reproduced
GET /groups/:id/merge_requests?my_reaction_emoji=star
```
`group_id` represents the ID of the group which contains the project where the MR resides.
Parameters:
| Attribute | Type | Required | Description |
| ------------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `id` | integer | yes | The ID of a group |
| `state` | string | no | Return all merge requests or just those that are `opened`, `closed`, or `merged` |
| `order_by` | string | no | Return merge requests ordered by `created_at` or `updated_at` fields. Default is `created_at` |
| `sort` | string | no | Return merge requests sorted in `asc` or `desc` order. Default is `desc` |
| `milestone` | string | no | Return merge requests for a specific milestone |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request |
| `labels` | string | no | Return merge requests matching a comma separated list of labels |
| `created_after` | datetime | no | Return merge requests created on or after the given time |
| `created_before` | datetime | no | Return merge requests created on or before the given time |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time |
| `updated_before` | datetime | no | Return merge requests updated on or before the given time |
| `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> |
| `author_id` | integer | no | Returns merge requests created by the given user `id` _([Introduced][ce-13060] in GitLab 9.5)_ |
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id` _([Introduced][ce-13060] in GitLab 9.5)_ |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji` _([Introduced][ce-14016] in GitLab 10.0)_ |
| `source_branch` | string | no | Return merge requests with the given source branch |
| `target_branch` | string | no | Return merge requests with the given target branch |
| `search` | string | no | Search merge requests against their `title` and `description` |
```json
[
{
"id": 1,
"iid": 1,
"target_branch": "master",
"source_branch": "test1",
"project_id": 3,
"title": "test1",
"state": "opened",
"created_at": "2017-04-29T08:46:00Z",
"updated_at": "2017-04-29T08:46:00Z",
"upvotes": 0,
"downvotes": 0,
"author": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"name": "Administrator",
"state": "active",
"created_at": "2012-04-29T08:46:00Z"
},
"assignee": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"name": "Administrator",
"state": "active",
"created_at": "2012-04-29T08:46:00Z"
},
"source_project_id": 2,
"target_project_id": 3,
"labels": [ ],
"description": "fixed login page css paddings",
"work_in_progress": false,
"milestone": {
"id": 5,
"iid": 1,
"project_id": 3,
"title": "v2.0",
"description": "Assumenda aut placeat expedita exercitationem labore sunt enim earum.",
"state": "closed",
"created_at": "2015-02-02T19:49:26.013Z",
"updated_at": "2015-02-02T19:49:26.013Z",
"due_date": null
},
"merge_when_pipeline_succeeds": true,
"merge_status": "can_be_merged",
"sha": "8888888888888888888888888888888888888888",
"merge_commit_sha": null,
"user_notes_count": 1,
"changes_count": "1",
"should_remove_source_branch": true,
"force_remove_source_branch": false,
"web_url": "http://example.com/example/example/merge_requests/1",
"discussion_locked": false,
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
"human_time_estimate": null,
"human_total_time_spent": null
}
}
]
```
## Get single MR ## Get single MR
Shows information about a single merge request. Shows information about a single merge request.
......
# Tips # Tips
> TODO: Add tips ## Clearing production compiled assets
To clear production compiled assets created with `yarn webpack-prod` you can run:
```
yarn clean
```
...@@ -120,6 +120,10 @@ Add `screenshot_and_save_page` in a `:js` spec to screenshot what Capybara ...@@ -120,6 +120,10 @@ Add `screenshot_and_save_page` in a `:js` spec to screenshot what Capybara
Add `screenshot_and_open_image` in a `:js` spec to screenshot what Capybara Add `screenshot_and_open_image` in a `:js` spec to screenshot what Capybara
"sees", and automatically open the image. "sees", and automatically open the image.
The HTML dumps created by this are missing CSS.
This results in them looking very different from the actual application.
There is a [small hack](https://gitlab.com/gitlab-org/gitlab-ce/snippets/1718469) to add CSS which makes debugging easier.
### Fast unit tests ### Fast unit tests
Some classes are well-isolated from Rails and you should be able to test them Some classes are well-isolated from Rails and you should be able to test them
......
...@@ -16,7 +16,7 @@ module API ...@@ -16,7 +16,7 @@ module API
args[:scope] = args[:scope].underscore if args[:scope] args[:scope] = args[:scope].underscore if args[:scope]
issues = IssuesFinder.new(current_user, args).execute issues = IssuesFinder.new(current_user, args).execute
.preload(:assignees, :labels, :notes, :timelogs) .preload(:assignees, :labels, :notes, :timelogs, :project)
issues.reorder(args[:order_by] => args[:sort]) issues.reorder(args[:order_by] => args[:sort])
end end
......
...@@ -61,6 +61,18 @@ module API ...@@ -61,6 +61,18 @@ module API
end end
end end
def serializer_options_for(merge_requests)
options = { with: Entities::MergeRequestBasic, current_user: current_user }
if params[:view] == 'simple'
options[:with] = Entities::MergeRequestSimple
else
options[:issuable_metadata] = issuable_meta_data(merge_requests, 'MergeRequest')
end
options
end
params :merge_requests_params do params :merge_requests_params do
optional :state, type: String, values: %w[opened closed merged all], default: 'all', optional :state, type: String, values: %w[opened closed merged all], default: 'all',
desc: 'Return opened, closed, merged, or all merge requests' desc: 'Return opened, closed, merged, or all merge requests'
...@@ -100,16 +112,26 @@ module API ...@@ -100,16 +112,26 @@ module API
authenticate! unless params[:scope] == 'all' authenticate! unless params[:scope] == 'all'
merge_requests = find_merge_requests merge_requests = find_merge_requests
options = { with: Entities::MergeRequestBasic, present merge_requests, serializer_options_for(merge_requests)
current_user: current_user } end
end
if params[:view] == 'simple' params do
options[:with] = Entities::MergeRequestSimple requires :id, type: String, desc: 'The ID of a group'
else end
options[:issuable_metadata] = issuable_meta_data(merge_requests, 'MergeRequest') resource :groups, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
end desc 'Get a list of group merge requests' do
success Entities::MergeRequestBasic
end
params do
use :merge_requests_params
end
get ":id/merge_requests" do
group = find_group!(params[:id])
present merge_requests, options merge_requests = find_merge_requests(group_id: group.id, include_subgroups: true)
present merge_requests, serializer_options_for(merge_requests)
end end
end end
...@@ -161,15 +183,8 @@ module API ...@@ -161,15 +183,8 @@ module API
merge_requests = find_merge_requests(project_id: user_project.id) merge_requests = find_merge_requests(project_id: user_project.id)
options = { with: Entities::MergeRequestBasic, options = serializer_options_for(merge_requests)
current_user: current_user, options[:project] = user_project
project: user_project }
if params[:view] == 'simple'
options[:with] = Entities::MergeRequestSimple
else
options[:issuable_metadata] = issuable_meta_data(merge_requests, 'MergeRequest')
end
present merge_requests, options present merge_requests, options
end end
......
...@@ -28,6 +28,7 @@ project_tree: ...@@ -28,6 +28,7 @@ project_tree:
- project_members: - project_members:
- :user - :user
- merge_requests: - merge_requests:
- :metrics
- notes: - notes:
- :author - :author
- events: - events:
......
...@@ -19,9 +19,10 @@ module Gitlab ...@@ -19,9 +19,10 @@ module Gitlab
label: :project_label, label: :project_label,
custom_attributes: 'ProjectCustomAttribute', custom_attributes: 'ProjectCustomAttribute',
project_badges: 'Badge', project_badges: 'Badge',
metrics: 'MergeRequest::Metrics',
ci_cd_settings: 'ProjectCiCdSetting' }.freeze ci_cd_settings: 'ProjectCiCdSetting' }.freeze
USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id created_by_id last_edited_by_id merge_user_id resolved_by_id closed_by_id].freeze USER_REFERENCES = %w[author_id assignee_id updated_by_id merged_by_id latest_closed_by_id user_id created_by_id last_edited_by_id merge_user_id resolved_by_id closed_by_id].freeze
PROJECT_REFERENCES = %w[project_id source_project_id target_project_id].freeze PROJECT_REFERENCES = %w[project_id source_project_id target_project_id].freeze
......
...@@ -4,7 +4,7 @@ module Gitlab ...@@ -4,7 +4,7 @@ module Gitlab
attach_to :active_record attach_to :active_record
def sql(event) def sql(event)
unless event.payload[:name] == 'CACHE' unless event.payload.fetch(:cached, event.payload[:name] == 'CACHE')
Transaction.current&.increment Transaction.current&.increment
end end
end end
......
...@@ -8,8 +8,13 @@ msgid "" ...@@ -8,8 +8,13 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gitlab 1.0.0\n" "Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
<<<<<<< HEAD
"POT-Creation-Date: 2018-05-30 10:16-0400\n" "POT-Creation-Date: 2018-05-30 10:16-0400\n"
"PO-Revision-Date: 2018-05-30 10:16-0400\n" "PO-Revision-Date: 2018-05-30 10:16-0400\n"
=======
"POT-Creation-Date: 2018-05-29 09:43-0500\n"
"PO-Revision-Date: 2018-05-29 09:43-0500\n"
>>>>>>> upstream/master
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n" "Language: \n"
...@@ -201,6 +206,21 @@ msgstr "" ...@@ -201,6 +206,21 @@ msgstr ""
msgid "2FA enabled" msgid "2FA enabled"
msgstr "" msgstr ""
msgid "403|Please contact your GitLab administrator to get the permission."
msgstr ""
msgid "403|You don't have the permission to access this page."
msgstr ""
msgid "404|Make sure the address is correct and the page hasn't moved."
msgstr ""
msgid "404|Page Not Found"
msgstr ""
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
msgstr ""
msgid "<strong>Removes</strong> source branch" msgid "<strong>Removes</strong> source branch"
msgstr "" msgstr ""
...@@ -1187,6 +1207,12 @@ msgstr "" ...@@ -1187,6 +1207,12 @@ msgstr ""
msgid "ClusterIntegration|Advanced options on this Kubernetes cluster's integration" msgid "ClusterIntegration|Advanced options on this Kubernetes cluster's integration"
msgstr "" msgstr ""
msgid "ClusterIntegration|An error occured while trying to fetch project zones: %{error}"
msgstr ""
msgid "ClusterIntegration|An error occured while trying to fetch your projects: %{error}"
msgstr ""
msgid "ClusterIntegration|Applications" msgid "ClusterIntegration|Applications"
msgstr "" msgstr ""
...@@ -1247,6 +1273,15 @@ msgstr "" ...@@ -1247,6 +1273,15 @@ msgstr ""
msgid "ClusterIntegration|Every new Google Cloud Platform (GCP) account receives $300 in credit upon %{sign_up_link}. In partnership with Google, GitLab is able to offer an additional $200 for new GCP accounts to get started with GitLab's Google Kubernetes Engine Integration." msgid "ClusterIntegration|Every new Google Cloud Platform (GCP) account receives $300 in credit upon %{sign_up_link}. In partnership with Google, GitLab is able to offer an additional $200 for new GCP accounts to get started with GitLab's Google Kubernetes Engine Integration."
msgstr "" msgstr ""
msgid "ClusterIntegration|Fetching machine types"
msgstr ""
msgid "ClusterIntegration|Fetching projects"
msgstr ""
msgid "ClusterIntegration|Fetching zones"
msgstr ""
msgid "ClusterIntegration|GitLab Integration" msgid "ClusterIntegration|GitLab Integration"
msgstr "" msgstr ""
...@@ -1352,7 +1387,20 @@ msgstr "" ...@@ -1352,7 +1387,20 @@ msgstr ""
msgid "ClusterIntegration|More information" msgid "ClusterIntegration|More information"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "ClusterIntegration|Multiple Kubernetes clusters are available in GitLab Enterprise Edition Premium and Ultimate" msgid "ClusterIntegration|Multiple Kubernetes clusters are available in GitLab Enterprise Edition Premium and Ultimate"
=======
msgid "ClusterIntegration|No machine types matched your search"
msgstr ""
msgid "ClusterIntegration|No projects found"
msgstr ""
msgid "ClusterIntegration|No projects matched your search"
msgstr ""
msgid "ClusterIntegration|No zones matched your search"
>>>>>>> upstream/master
msgstr "" msgstr ""
msgid "ClusterIntegration|Note:" msgid "ClusterIntegration|Note:"
...@@ -1367,9 +1415,6 @@ msgstr "" ...@@ -1367,9 +1415,6 @@ msgstr ""
msgid "ClusterIntegration|Please make sure that your Google account meets the following requirements:" msgid "ClusterIntegration|Please make sure that your Google account meets the following requirements:"
msgstr "" msgstr ""
msgid "ClusterIntegration|Project ID"
msgstr ""
msgid "ClusterIntegration|Project namespace" msgid "ClusterIntegration|Project namespace"
msgstr "" msgstr ""
...@@ -1400,19 +1445,40 @@ msgstr "" ...@@ -1400,19 +1445,40 @@ msgstr ""
msgid "ClusterIntegration|Save changes" msgid "ClusterIntegration|Save changes"
msgstr "" msgstr ""
msgid "ClusterIntegration|Search machine types"
msgstr ""
msgid "ClusterIntegration|Search projects"
msgstr ""
msgid "ClusterIntegration|Search zones"
msgstr ""
msgid "ClusterIntegration|Security" msgid "ClusterIntegration|Security"
msgstr "" msgstr ""
msgid "ClusterIntegration|See and edit the details for your Kubernetes cluster" msgid "ClusterIntegration|See and edit the details for your Kubernetes cluster"
msgstr "" msgstr ""
msgid "ClusterIntegration|See machine types" msgid "ClusterIntegration|See zones"
msgstr "" msgstr ""
msgid "ClusterIntegration|See your projects" msgid "ClusterIntegration|Select machine type"
msgstr "" msgstr ""
msgid "ClusterIntegration|See zones" msgid "ClusterIntegration|Select project"
msgstr ""
msgid "ClusterIntegration|Select project and zone to choose machine type"
msgstr ""
msgid "ClusterIntegration|Select project to choose zone"
msgstr ""
msgid "ClusterIntegration|Select zone"
msgstr ""
msgid "ClusterIntegration|Select zone to choose machine type"
msgstr "" msgstr ""
msgid "ClusterIntegration|Service token" msgid "ClusterIntegration|Service token"
...@@ -1445,6 +1511,9 @@ msgstr "" ...@@ -1445,6 +1511,9 @@ msgstr ""
msgid "ClusterIntegration|Token" msgid "ClusterIntegration|Token"
msgstr "" msgstr ""
msgid "ClusterIntegration|Validating project billing status"
msgstr ""
msgid "ClusterIntegration|With a Kubernetes cluster associated to this project, you can use review apps, deploy your applications, run your pipelines, and much more in an easy way." msgid "ClusterIntegration|With a Kubernetes cluster associated to this project, you can use review apps, deploy your applications, run your pipelines, and much more in an easy way."
msgstr "" msgstr ""
...@@ -2473,7 +2542,14 @@ msgstr "" ...@@ -2473,7 +2542,14 @@ msgstr ""
msgid "GeoNodes|Full" msgid "GeoNodes|Full"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "GeoNodes|GitLab version" msgid "GeoNodes|GitLab version"
=======
msgid "Go Back"
msgstr ""
msgid "Go back"
>>>>>>> upstream/master
msgstr "" msgstr ""
msgid "GeoNodes|GitLab version does not match the primary node version" msgid "GeoNodes|GitLab version does not match the primary node version"
...@@ -3331,6 +3407,18 @@ msgstr "" ...@@ -3331,6 +3407,18 @@ msgstr ""
msgid "Name new label" msgid "Name new label"
msgstr "" msgstr ""
msgid "Nav|Help"
msgstr ""
msgid "Nav|Home"
msgstr ""
msgid "Nav|Sign In / Register"
msgstr ""
msgid "Nav|Sign out and sign in with a different account"
msgstr ""
msgid "New Issue" msgid "New Issue"
msgid_plural "New Issues" msgid_plural "New Issues"
msgstr[0] "" msgstr[0] ""
...@@ -3798,9 +3886,6 @@ msgstr "" ...@@ -3798,9 +3886,6 @@ msgstr ""
msgid "Play" msgid "Play"
msgstr "" msgstr ""
msgid "Please <a href=%{link_to_billing} target=\"_blank\" rel=\"noopener noreferrer\">enable billing for one of your projects to be able to create a Kubernetes cluster</a>, then try again."
msgstr ""
msgid "Please accept the Terms of Service before continuing." msgid "Please accept the Terms of Service before continuing."
msgstr "" msgstr ""
...@@ -4370,6 +4455,9 @@ msgstr "" ...@@ -4370,6 +4455,9 @@ msgstr ""
msgid "Search files" msgid "Search files"
msgstr "" msgstr ""
msgid "Search for projects, issues, etc."
msgstr ""
msgid "Search milestones" msgid "Search milestones"
msgstr "" msgstr ""
...@@ -4385,7 +4473,11 @@ msgstr "" ...@@ -4385,7 +4473,11 @@ msgstr ""
msgid "Seconds to wait for a storage access attempt" msgid "Seconds to wait for a storage access attempt"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "Security report" msgid "Security report"
=======
msgid "Select"
>>>>>>> upstream/master
msgstr "" msgstr ""
msgid "Select Archive Format" msgid "Select Archive Format"
...@@ -4406,6 +4498,15 @@ msgstr "" ...@@ -4406,6 +4498,15 @@ msgstr ""
msgid "Select branch/tag" msgid "Select branch/tag"
msgstr "" msgstr ""
msgid "Select project"
msgstr ""
msgid "Select project and zone to choose machine type"
msgstr ""
msgid "Select project to choose zone"
msgstr ""
msgid "Select source branch" msgid "Select source branch"
msgstr "" msgstr ""
...@@ -4546,9 +4647,12 @@ msgstr "" ...@@ -4546,9 +4647,12 @@ msgstr ""
msgid "Something went wrong when toggling the button" msgid "Something went wrong when toggling the button"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "Something went wrong while fetching group member contributions" msgid "Something went wrong while fetching group member contributions"
msgstr "" msgstr ""
=======
>>>>>>> upstream/master
msgid "Something went wrong while fetching the latest pipeline status." msgid "Something went wrong while fetching the latest pipeline status."
msgstr "" msgstr ""
...@@ -5380,6 +5484,7 @@ msgstr "" ...@@ -5380,6 +5484,7 @@ msgstr ""
msgid "Update your group name, description, avatar, and other general settings." msgid "Update your group name, description, avatar, and other general settings."
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "Upgrade your plan to activate Advanced Global Search." msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "" msgstr ""
...@@ -5395,6 +5500,8 @@ msgstr "" ...@@ -5395,6 +5500,8 @@ msgstr ""
msgid "Upgrade your plan to improve Issue boards." msgid "Upgrade your plan to improve Issue boards."
msgstr "" msgstr ""
=======
>>>>>>> upstream/master
msgid "Upload New File" msgid "Upload New File"
msgstr "" msgstr ""
...@@ -5494,9 +5601,6 @@ msgstr "" ...@@ -5494,9 +5601,6 @@ msgstr ""
msgid "Want to see the data? Please ask an administrator for access." msgid "Want to see the data? Please ask an administrator for access."
msgstr "" msgstr ""
msgid "We could not verify that one of your projects on GCP has billing enabled. Please try again."
msgstr ""
msgid "We don't have enough data to show this stage." msgid "We don't have enough data to show this stage."
msgstr "" msgstr ""
......
{ {
"private": true, "private": true,
"scripts": { "scripts": {
"clean": "rm -rf public/assets tmp/cache/*-loader",
"dev-server": "nodemon -w 'config/webpack.config.js' --exec 'webpack-dev-server --config config/webpack.config.js'", "dev-server": "nodemon -w 'config/webpack.config.js' --exec 'webpack-dev-server --config config/webpack.config.js'",
"eslint": "eslint --max-warnings 0 --ext .js,.vue .", "eslint": "eslint --max-warnings 0 --ext .js,.vue .",
"eslint-fix": "eslint --max-warnings 0 --ext .js,.vue --fix .", "eslint-fix": "eslint --max-warnings 0 --ext .js,.vue --fix .",
......
...@@ -147,7 +147,11 @@ describe ApplicationController do ...@@ -147,7 +147,11 @@ describe ApplicationController do
end end
describe '#authenticate_sessionless_user!' do describe '#authenticate_sessionless_user!' do
<<<<<<< HEAD
describe "authenticating a user from a feed token" do describe "authenticating a user from a feed token" do
=======
describe 'authenticating a user from a feed token' do
>>>>>>> upstream/master
controller(described_class) do controller(described_class) do
def index def index
render text: 'authenticated' render text: 'authenticated'
...@@ -182,7 +186,11 @@ describe ApplicationController do ...@@ -182,7 +186,11 @@ describe ApplicationController do
context "when the 'feed_token' param is populated with an invalid feed token" do context "when the 'feed_token' param is populated with an invalid feed token" do
it "doesn't log the user" do it "doesn't log the user" do
<<<<<<< HEAD
get :index, feed_token: "token", format: :atom get :index, feed_token: "token", format: :atom
=======
get :index, feed_token: 'token', format: :atom
>>>>>>> upstream/master
expect(response.status).not_to eq 200 expect(response.status).not_to eq 200
expect(response.body).not_to eq 'authenticated' expect(response.body).not_to eq 'authenticated'
end end
......
require 'spec_helper'
describe 'Error Pages' do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
before do
sign_in(user)
end
shared_examples 'shows nav links' do
it 'shows nav links' do
expect(page).to have_link("Home", href: root_path)
expect(page).to have_link("Help", href: help_path)
expect(page).to have_link(nil, href: destroy_user_session_path)
end
end
describe '404' do
before do
visit '/not-a-real-page'
end
it 'allows user to search' do
fill_in 'search', with: 'something'
click_button 'Search'
expect(page).to have_current_path(%r{^/search\?.*search=something.*})
end
it_behaves_like 'shows nav links'
end
describe '403' do
before do
visit '/'
visit edit_project_path(project)
end
it_behaves_like 'shows nav links'
end
end
...@@ -17,8 +17,8 @@ feature 'Project milestone' do ...@@ -17,8 +17,8 @@ feature 'Project milestone' do
it 'shows issues tab' do it 'shows issues tab' do
within('#content-body') do within('#content-body') do
expect(page).to have_link 'Issues', href: '#tab-issues' expect(page).to have_link 'Issues', href: '#tab-issues'
expect(page).to have_selector '.nav-links li.active', count: 1 expect(page).to have_selector '.nav-links li a.active', count: 1
expect(find('.nav-links li.active')).to have_content 'Issues' expect(find('.nav-links li a.active')).to have_content 'Issues'
end end
end end
...@@ -44,8 +44,8 @@ feature 'Project milestone' do ...@@ -44,8 +44,8 @@ feature 'Project milestone' do
it 'hides issues tab' do it 'hides issues tab' do
within('#content-body') do within('#content-body') do
expect(page).not_to have_link 'Issues', href: '#tab-issues' expect(page).not_to have_link 'Issues', href: '#tab-issues'
expect(page).to have_selector '.nav-links li.active', count: 1 expect(page).to have_selector '.nav-links li a.active', count: 1
expect(find('.nav-links li.active')).to have_content 'Merge Requests' expect(find('.nav-links li a.active')).to have_content 'Merge Requests'
end end
end end
......
...@@ -379,7 +379,7 @@ describe 'Pipeline', :js do ...@@ -379,7 +379,7 @@ describe 'Pipeline', :js do
end end
it 'fails to access the page' do it 'fails to access the page' do
expect(page).to have_content('Access Denied') expect(page).to have_title('Access Denied')
end end
end end
end end
......
...@@ -353,3 +353,8 @@ lfs_file_locks: ...@@ -353,3 +353,8 @@ lfs_file_locks:
- user - user
project_badges: project_badges:
- project - project
metrics:
- merge_request
- latest_closed_by
- merged_by
- pipeline
...@@ -119,6 +119,25 @@ describe Gitlab::ImportExport::RelationFactory do ...@@ -119,6 +119,25 @@ describe Gitlab::ImportExport::RelationFactory do
end end
end end
context 'overrided model with pluralized name' do
let(:relation_sym) { :metrics }
let(:relation_hash) do
{
'id' => 99,
'merge_request_id' => 99,
'merged_at' => Time.now,
'merged_by_id' => 99,
'latest_closed_at' => nil,
'latest_closed_by_id' => nil
}
end
it 'does not raise errors' do
expect { created_object }.not_to raise_error
end
end
context 'Project references' do context 'Project references' do
let(:relation_sym) { :project_foo_model } let(:relation_sym) { :project_foo_model }
let(:relation_hash) do let(:relation_hash) do
......
...@@ -208,6 +208,19 @@ MergeRequestDiffFile: ...@@ -208,6 +208,19 @@ MergeRequestDiffFile:
- b_mode - b_mode
- too_large - too_large
- binary - binary
MergeRequest::Metrics:
- id
- created_at
- updated_at
- merge_request_id
- pipeline_id
- latest_closed_by_id
- latest_closed_at
- merged_by_id
- merged_at
- latest_build_started_at
- latest_build_finished_at
- first_deployed_to_production_at
Ci::Pipeline: Ci::Pipeline:
- id - id
- project_id - project_id
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20180521162137_migrate_remaining_mr_metrics_populating_background_migration.rb')
describe MigrateRemainingMrMetricsPopulatingBackgroundMigration, :migration, :sidekiq do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:mrs) { table(:merge_requests) }
before do
namespaces.create!(id: 1, name: 'foo', path: 'foo')
projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1', namespace_id: 1)
projects.create!(id: 456, name: 'gitlab2', path: 'gitlab2', namespace_id: 1)
projects.create!(id: 789, name: 'gitlab3', path: 'gitlab3', namespace_id: 1)
mrs.create!(title: 'foo', target_branch: 'target', source_branch: 'source', target_project_id: 123)
mrs.create!(title: 'bar', target_branch: 'target', source_branch: 'source', target_project_id: 456)
mrs.create!(title: 'kux', target_branch: 'target', source_branch: 'source', target_project_id: 789)
end
it 'correctly schedules background migrations' do
stub_const("#{described_class.name}::BATCH_SIZE", 2)
Sidekiq::Testing.fake! do
Timecop.freeze do
migrate!
expect(described_class::MIGRATION)
.to be_scheduled_delayed_migration(10.minutes, mrs.first.id, mrs.second.id)
expect(described_class::MIGRATION)
.to be_scheduled_delayed_migration(20.minutes, mrs.third.id, mrs.third.id)
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
end
end
end
end
...@@ -219,11 +219,11 @@ describe Ci::BuildPresenter do ...@@ -219,11 +219,11 @@ describe Ci::BuildPresenter do
end end
describe '#callout_failure_message' do describe '#callout_failure_message' do
let(:build) { create(:ci_build, :failed, :script_failure) } let(:build) { create(:ci_build, :failed, :api_failure) }
it 'returns a verbose failure reason' do it 'returns a verbose failure reason' do
description = subject.callout_failure_message description = subject.callout_failure_message
expect(description).to eq('There has been a script failure. Check the job log for more information') expect(description).to eq('There has been an API failure, please try again')
end end
end end
......
This diff is collapsed.
...@@ -131,7 +131,7 @@ describe JobEntity do ...@@ -131,7 +131,7 @@ describe JobEntity do
end end
context 'when job failed' do context 'when job failed' do
let(:job) { create(:ci_build, :script_failure) } let(:job) { create(:ci_build, :api_failure) }
it 'contains details' do it 'contains details' do
expect(subject[:status]).to include :icon, :favicon, :text, :label, :tooltip expect(subject[:status]).to include :icon, :favicon, :text, :label, :tooltip
...@@ -142,20 +142,20 @@ describe JobEntity do ...@@ -142,20 +142,20 @@ describe JobEntity do
end end
it 'should indicate the failure reason on tooltip' do it 'should indicate the failure reason on tooltip' do
expect(subject[:status][:tooltip]).to eq('failed <br> (script failure)') expect(subject[:status][:tooltip]).to eq('failed <br> (API failure)')
end end
it 'should include a callout message with a verbose output' do it 'should include a callout message with a verbose output' do
expect(subject[:callout_message]).to eq('There has been a script failure. Check the job log for more information') expect(subject[:callout_message]).to eq('There has been an API failure, please try again')
end end
it 'should state that it is not recoverable' do it 'should state that it is not recoverable' do
expect(subject[:recoverable]).to be_falsy expect(subject[:recoverable]).to be_truthy
end end
end end
context 'when job is allowed to fail' do context 'when job is allowed to fail' do
let(:job) { create(:ci_build, :allowed_to_fail, :script_failure) } let(:job) { create(:ci_build, :allowed_to_fail, :api_failure) }
it 'contains details' do it 'contains details' do
expect(subject[:status]).to include :icon, :favicon, :text, :label, :tooltip expect(subject[:status]).to include :icon, :favicon, :text, :label, :tooltip
...@@ -166,15 +166,24 @@ describe JobEntity do ...@@ -166,15 +166,24 @@ describe JobEntity do
end end
it 'should indicate the failure reason on tooltip' do it 'should indicate the failure reason on tooltip' do
expect(subject[:status][:tooltip]).to eq('failed <br> (script failure) (allowed to fail)') expect(subject[:status][:tooltip]).to eq('failed <br> (API failure) (allowed to fail)')
end end
it 'should include a callout message with a verbose output' do it 'should include a callout message with a verbose output' do
expect(subject[:callout_message]).to eq('There has been a script failure. Check the job log for more information') expect(subject[:callout_message]).to eq('There has been an API failure, please try again')
end end
it 'should state that it is not recoverable' do it 'should state that it is not recoverable' do
expect(subject[:recoverable]).to be_falsy expect(subject[:recoverable]).to be_truthy
end
end
context 'when the job failed with a script failure' do
let(:job) { create(:ci_build, :failed, :script_failure) }
it 'should not include callout message or recoverable keys' do
expect(subject).not_to include('callout_message')
expect(subject).not_to include('recoverable')
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment