summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/deploy_keys/components/key.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js9
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js22
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js4
-rw-r--r--app/assets/stylesheets/framework/buttons.scss1
-rw-r--r--app/assets/stylesheets/pages/repo.scss10
-rw-r--r--app/helpers/submodule_helper.rb12
-rw-r--r--app/models/project.rb2
-rw-r--r--app/policies/group_policy.rb3
-rw-r--r--app/policies/project_policy.rb2
-rw-r--r--app/views/admin/appearances/_form.html.haml4
-rw-r--r--app/views/admin/hooks/index.html.haml2
-rw-r--r--app/views/projects/pipelines_settings/_show.html.haml4
-rw-r--r--app/views/projects/settings/integrations/_project_hook.html.haml2
-rw-r--r--app/views/shared/_target_switcher.html.haml20
-rw-r--r--app/views/shared/boards/components/_board.html.haml2
-rw-r--r--changelogs/unreleased/33287-fix-mr-widget-errors-with-external-services.yml5
-rw-r--r--changelogs/unreleased/34259-project-denial-of-service-via-gitmodules-fix.yml5
-rw-r--r--changelogs/unreleased/issue_32215.yml5
-rw-r--r--lib/gitlab/i18n.rb3
-rw-r--r--locale/bg/gitlab.po20
-rw-r--r--locale/de/gitlab.po50
-rw-r--r--locale/eo/gitlab.po20
-rw-r--r--locale/es/gitlab.po20
-rw-r--r--locale/fr/gitlab.po20
-rw-r--r--locale/it/gitlab.po20
-rw-r--r--locale/ja/gitlab.po20
-rw-r--r--locale/ko/gitlab.po20
-rw-r--r--locale/nl_NL/gitlab.po1474
-rw-r--r--locale/pt_BR/gitlab.po20
-rw-r--r--locale/ru/gitlab.po20
-rw-r--r--locale/uk/gitlab.po20
-rw-r--r--locale/zh_CN/gitlab.po136
-rw-r--r--locale/zh_HK/gitlab.po20
-rw-r--r--locale/zh_TW/gitlab.po52
-rw-r--r--qa/qa/page/main/menu.rb2
-rw-r--r--spec/controllers/projects/pipelines_settings_controller_spec.rb43
-rw-r--r--spec/features/merge_requests/widget_spec.rb18
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/user/admins.json4
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/user/basics.json4
-rw-r--r--spec/helpers/submodule_helper_spec.rb6
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js20
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js60
-rw-r--r--spec/javascripts/vue_mr_widget/mr_widget_options_spec.js14
-rw-r--r--spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js34
-rw-r--r--spec/policies/group_policy_spec.rb18
-rw-r--r--spec/policies/project_policy_spec.rb4
-rw-r--r--spec/requests/api/users_spec.rb51
52 files changed, 2134 insertions, 205 deletions
diff --git a/app/assets/javascripts/deploy_keys/components/key.vue b/app/assets/javascripts/deploy_keys/components/key.vue
index 904f7f64fa8..b41d464475f 100644
--- a/app/assets/javascripts/deploy_keys/components/key.vue
+++ b/app/assets/javascripts/deploy_keys/components/key.vue
@@ -73,7 +73,7 @@
</span>
<a
v-if="deployKey.can_edit"
- class="btn btn-small"
+ class="btn btn-sm"
:href="editDeployKeyPath"
>
Edit
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js
index aaca42e3ebc..219ff94924e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js
@@ -72,12 +72,12 @@ export default {
<a
href="#modal_merge_info"
data-toggle="modal"
- class="btn btn-small inline">
+ class="btn btn-sm inline">
Check out branch
</a>
<span class="dropdown prepend-left-10">
<a
- class="btn btn-small inline dropdown-toggle"
+ class="btn btn-sm inline dropdown-toggle"
data-toggle="dropdown"
aria-label="Download as"
role="button">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js
index 6c2e9ba1d30..c79b5c720eb 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js
@@ -12,6 +12,9 @@ export default {
ciIcon,
},
computed: {
+ hasPipeline() {
+ return this.mr.pipeline && Object.keys(this.mr.pipeline).length > 0;
+ },
hasCIError() {
const { hasCI, ciStatus } = this.mr;
@@ -28,7 +31,9 @@ export default {
},
},
template: `
- <div class="mr-widget-heading">
+ <div
+ v-if="hasPipeline || hasCIError"
+ class="mr-widget-heading">
<div class="ci-widget media">
<template v-if="hasCIError">
<div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error append-right-10">
@@ -40,7 +45,7 @@ export default {
Could not connect to the CI server. Please check your settings and try again
</div>
</template>
- <template v-else>
+ <template v-else-if="hasPipeline">
<div class="ci-status-icon append-right-10">
<a
class="icon-link"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.js
index b01c923311b..703f3a56a34 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.js
@@ -27,7 +27,7 @@ export default {
<button
v-if="showDisabledButton"
type="button"
- class="btn btn-success btn-small"
+ class="btn btn-success btn-sm"
disabled="true">
Merge
</button>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js
index 2b16a2d6817..b4e4a6aa161 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js
@@ -11,7 +11,7 @@ export default {
<status-icon status="failed" />
<button
type="button"
- class="btn btn-success btn-small"
+ class="btn btn-success btn-sm"
disabled="true">
Merge
</button>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
index 1fb7150d20e..ad709da51ee 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
@@ -29,6 +29,9 @@ export default {
statusIcon,
},
computed: {
+ shouldShowMergeWhenPipelineSucceedsText() {
+ return this.mr.isPipelineActive;
+ },
commitMessageLinkTitle() {
const withDesc = 'Include description in commit message';
const withoutDesc = "Don't include description in commit message";
@@ -36,7 +39,7 @@ export default {
return this.useCommitMessageWithDescription ? withoutDesc : withDesc;
},
mergeButtonClass() {
- const defaultClass = 'btn btn-small btn-success accept-merge-request';
+ const defaultClass = 'btn btn-sm btn-success accept-merge-request';
const failedClass = `${defaultClass} btn-danger`;
const inActionClass = `${defaultClass} btn-info`;
const { pipeline, isPipelineActive, isPipelineFailed, hasCI, ciStatus } = this.mr;
@@ -56,7 +59,7 @@ export default {
mergeButtonText() {
if (this.isMergingImmediately) {
return 'Merge in progress';
- } else if (this.mr.isPipelineActive) {
+ } else if (this.shouldShowMergeWhenPipelineSucceedsText) {
return 'Merge when pipeline succeeds';
}
@@ -68,7 +71,7 @@ export default {
isMergeButtonDisabled() {
const { commitMessage } = this;
return Boolean(!commitMessage.length
- || !this.isMergeAllowed()
+ || !this.shouldShowMergeControls()
|| this.isMakingRequest
|| this.mr.preventMerge);
},
@@ -82,7 +85,12 @@ export default {
},
methods: {
isMergeAllowed() {
- return !(this.mr.onlyAllowMergeIfPipelineSucceeds && this.mr.isPipelineFailed);
+ return !this.mr.onlyAllowMergeIfPipelineSucceeds ||
+ this.mr.isPipelinePassing ||
+ this.mr.isPipelineSkipped;
+ },
+ shouldShowMergeControls() {
+ return this.isMergeAllowed() || this.shouldShowMergeWhenPipelineSucceedsText;
},
updateCommitMessage() {
const cmwd = this.mr.commitMessageWithDescription;
@@ -219,7 +227,7 @@ export default {
v-if="shouldShowMergeOptionsDropdown"
:disabled="isMergeButtonDisabled"
type="button"
- class="btn btn-small btn-info dropdown-toggle js-merge-moment"
+ class="btn btn-sm btn-info dropdown-toggle js-merge-moment"
data-toggle="dropdown"
aria-label="Select merge moment">
<i
@@ -261,7 +269,7 @@ export default {
</ul>
</span>
<div class="media-body-wrap space-children">
- <template v-if="isMergeAllowed()">
+ <template v-if="shouldShowMergeControls()">
<label>
<input
id="remove-source-branch-input"
@@ -286,7 +294,7 @@ export default {
</template>
<template v-else>
<span class="bold">
- The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure
+ The pipeline for this merge request has not succeeded yet
</span>
</template>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
index 0042c48816f..2f237262028 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
@@ -57,7 +57,7 @@ export default {
return stateMaps.statesToShowHelpWidget.indexOf(this.mr.state) > -1;
},
shouldRenderPipelines() {
- return Object.keys(this.mr.pipeline).length || this.mr.hasCI;
+ return this.mr.hasCI;
},
shouldRenderRelatedLinks() {
return this.mr.relatedLinks;
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index fbea764b739..29464662578 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -85,7 +85,9 @@ export default class MergeRequestStore {
this.ciEnvironmentsStatusPath = data.ci_environments_status_path;
this.hasCI = data.has_ci;
this.ciStatus = data.ci_status;
- this.isPipelineFailed = this.ciStatus ? (this.ciStatus === 'failed' || this.ciStatus === 'canceled') : false;
+ this.isPipelineFailed = this.ciStatus === 'failed' || this.ciStatus === 'canceled';
+ this.isPipelinePassing = this.ciStatus === 'success' || this.ciStatus === 'success_with_warnings';
+ this.isPipelineSkipped = this.ciStatus === 'skipped';
this.pipelineDetailedStatus = pipelineStatus;
this.isPipelineActive = data.pipeline ? data.pipeline.active : false;
this.isPipelineBlocked = pipelineStatus ? pipelineStatus.group === 'manual' : false;
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index 82350c36df0..4f208df4216 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -140,7 +140,6 @@
outline: 0;
}
- &.btn-small,
&.btn-sm {
padding: 4px 10px;
font-size: 13px;
diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss
index 7dfcf7b7d9c..4d4d92f9494 100644
--- a/app/assets/stylesheets/pages/repo.scss
+++ b/app/assets/stylesheets/pages/repo.scss
@@ -56,7 +56,6 @@
.tree-content-holder {
display: flex;
- max-height: 100vh;
min-height: 300px;
}
@@ -156,7 +155,7 @@
list-style-type: none;
background: $gray-normal;
display: inline-block;
- padding: 10px 18px;
+ padding: #{$gl-padding / 2} $gl-padding;
border-right: 1px solid $white-dark;
border-bottom: 1px solid $white-dark;
white-space: nowrap;
@@ -180,10 +179,9 @@
a {
@include str-truncated(100px);
color: $black;
- width: 100px;
- text-align: center;
vertical-align: middle;
text-decoration: none;
+ margin-right: 12px;
&.close {
width: auto;
@@ -193,6 +191,10 @@
}
}
+ .close-icon:hover {
+ color: $hint-color;
+ }
+
.close-icon,
.unsaved-icon {
float: right;
diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb
index 88f7702db1e..40d69e30188 100644
--- a/app/helpers/submodule_helper.rb
+++ b/app/helpers/submodule_helper.rb
@@ -87,10 +87,14 @@ module SubmoduleHelper
namespace = @project.namespace.full_path
end
- [
- namespace_project_path(namespace, base),
- namespace_project_tree_path(namespace, base, commit)
- ]
+ begin
+ [
+ namespace_project_path(namespace, base),
+ namespace_project_tree_path(namespace, base, commit)
+ ]
+ rescue ActionController::UrlGenerationError
+ [nil, nil]
+ end
end
def sanitize_submodule_url(url)
diff --git a/app/models/project.rb b/app/models/project.rb
index 94ae0acbe1a..f7221e4f3b2 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -192,7 +192,7 @@ class Project < ActiveRecord::Base
accepts_nested_attributes_for :variables, allow_destroy: true
accepts_nested_attributes_for :project_feature, update_only: true
accepts_nested_attributes_for :import_data
- accepts_nested_attributes_for :auto_devops
+ accepts_nested_attributes_for :auto_devops, update_only: true
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 420991ff6d6..8af9738d75c 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -9,6 +9,7 @@ class GroupPolicy < BasePolicy
condition(:has_access) { access_level != GroupMember::NO_ACCESS }
condition(:guest) { access_level >= GroupMember::GUEST }
+ condition(:developer) { access_level >= GroupMember::DEVELOPER }
condition(:owner) { access_level >= GroupMember::OWNER }
condition(:master) { access_level >= GroupMember::MASTER }
condition(:reporter) { access_level >= GroupMember::REPORTER }
@@ -33,11 +34,11 @@ class GroupPolicy < BasePolicy
rule { admin } .enable :read_group
rule { has_projects } .enable :read_group
+ rule { developer }.enable :admin_milestones
rule { reporter }.enable :admin_label
rule { master }.policy do
enable :create_projects
- enable :admin_milestones
enable :admin_pipeline
enable :admin_build
end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index a925fac7d3e..b7b5bd34189 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -155,6 +155,7 @@ class ProjectPolicy < BasePolicy
rule { can?(:developer_access) }.policy do
enable :admin_merge_request
+ enable :admin_milestone
enable :update_merge_request
enable :create_commit_status
enable :update_commit_status
@@ -178,7 +179,6 @@ class ProjectPolicy < BasePolicy
enable :update_project_snippet
enable :update_environment
enable :update_deployment
- enable :admin_milestone
enable :admin_project_snippet
enable :admin_project_member
enable :admin_note
diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml
index e403a9da616..935787d1a4a 100644
--- a/app/views/admin/appearances/_form.html.haml
+++ b/app/views/admin/appearances/_form.html.haml
@@ -21,7 +21,7 @@
= image_tag @appearance.logo_url, class: 'appearance-logo-preview'
- if @appearance.persisted?
%br
- = link_to 'Remove logo', logo_admin_appearances_path, data: { confirm: "Logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-logo"
+ = link_to 'Remove logo', logo_admin_appearances_path, data: { confirm: "Logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-logo"
%hr
= f.hidden_field :logo_cache
= f.file_field :logo, class: ""
@@ -38,7 +38,7 @@
= image_tag @appearance.header_logo_url, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
- = link_to 'Remove header logo', header_logos_admin_appearances_path, data: { confirm: "Header logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-logo"
+ = link_to 'Remove header logo', header_logos_admin_appearances_path, data: { confirm: "Header logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-logo"
%hr
= f.hidden_field :header_logo_cache
= f.file_field :header_logo, class: ""
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
index fed6002528d..b6e1df5f3ac 100644
--- a/app/views/admin/hooks/index.html.haml
+++ b/app/views/admin/hooks/index.html.haml
@@ -22,7 +22,7 @@
- @hooks.each do |hook|
%li
.controls
- = render 'shared/web_hooks/test_button', triggers: SystemHook::TRIGGERS, hook: hook, button_class: 'btn-small'
+ = render 'shared/web_hooks/test_button', triggers: SystemHook::TRIGGERS, hook: hook, button_class: 'btn-sm'
= link_to 'Edit', edit_admin_hook_path(hook), class: 'btn btn-sm'
= link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: 'btn btn-remove btn-sm'
.monospace= hook.url
diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml
index 324cd423ede..2aceb4b529c 100644
--- a/app/views/projects/pipelines_settings/_show.html.haml
+++ b/app/views/projects/pipelines_settings/_show.html.haml
@@ -25,8 +25,8 @@
%span.descr
A specific .gitlab-ci.yml file needs to be specified before you can begin using Continious Integration and Delivery.
.radio
- = form.label :enabled do
- = form.radio_button :enabled, nil
+ = form.label :enabled_nil do
+ = form.radio_button :enabled, ''
%strong
Instance default (status: #{current_application_settings.auto_devops_enabled?})
%br
diff --git a/app/views/projects/settings/integrations/_project_hook.html.haml b/app/views/projects/settings/integrations/_project_hook.html.haml
index d5792e95f5a..82516cb4bcf 100644
--- a/app/views/projects/settings/integrations/_project_hook.html.haml
+++ b/app/views/projects/settings/integrations/_project_hook.html.haml
@@ -10,7 +10,7 @@
%span.append-right-10.inline
SSL Verification: #{hook.enable_ssl_verification ? 'enabled' : 'disabled'}
= link_to 'Edit', edit_project_hook_path(@project, hook), class: 'btn btn-sm'
- = render 'shared/web_hooks/test_button', triggers: ProjectHook::TRIGGERS, hook: hook, button_class: 'btn-small'
+ = render 'shared/web_hooks/test_button', triggers: ProjectHook::TRIGGERS, hook: hook, button_class: 'btn-sm'
= link_to project_hook_path(@project, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-transparent' do
%span.sr-only Remove
= icon('trash')
diff --git a/app/views/shared/_target_switcher.html.haml b/app/views/shared/_target_switcher.html.haml
index 9236868652f..bbe9692a7da 100644
--- a/app/views/shared/_target_switcher.html.haml
+++ b/app/views/shared/_target_switcher.html.haml
@@ -1,5 +1,5 @@
- dropdown_toggle_text = @ref || @project.default_branch
-= form_tag nil, method: :get, style: { display: 'none' }, class: "project-refs-target-form" do
+= form_tag nil, method: :get, class: "project-refs-form project-refs-target-form" do
= hidden_field_tag :destination, destination
- if defined?(path)
= hidden_field_tag :path, path
@@ -7,14 +7,10 @@
= hidden_field_tag key, value, id: nil
.dropdown
= dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_project_path(@project, find: ['branches']), field_name: 'ref', input_field_name: 'new-branch', submit_form_on_click: true, visit: false }, { toggle_class: "js-project-refs-dropdown" }
- %ul.dropdown-menu.dropdown-menu-selectable.git-revision-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
- %li
- = dropdown_title _("Create a new branch")
- %li
- = dropdown_input _("Create a new branch")
- %li
- = dropdown_title _("Select existing branch"), options: {close: false}
- %li
- = dropdown_filter _("Search branches and tags")
- = dropdown_content
- = dropdown_loading
+ .dropdown-menu.dropdown-menu-selectable.git-revision-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
+ = dropdown_title _("Create a new branch")
+ = dropdown_input _("Create a new branch")
+ = dropdown_title _("Select existing branch"), options: {close: false}
+ = dropdown_filter _("Search branches and tags")
+ = dropdown_content
+ = dropdown_loading
diff --git a/app/views/shared/boards/components/_board.html.haml b/app/views/shared/boards/components/_board.html.haml
index c5a8b32c772..c687e66fd43 100644
--- a/app/views/shared/boards/components/_board.html.haml
+++ b/app/views/shared/boards/components/_board.html.haml
@@ -27,7 +27,7 @@
%span.issue-count-badge-count.pull-left{ ":class" => '{ "has-btn": list.type !== "closed" && !disabled }' }
{{ list.issuesSize }}
- if can?(current_user, :admin_list, current_board_parent)
- %button.issue-count-badge-add-button.btn.btn-small.btn-default.has-tooltip.js-no-trigger-collapse{ type: "button",
+ %button.issue-count-badge-add-button.btn.btn-sm.btn-default.has-tooltip.js-no-trigger-collapse{ type: "button",
"@click" => "showNewIssueForm",
"v-if" => 'list.type !== "closed"',
"aria-label" => "New issue",
diff --git a/changelogs/unreleased/33287-fix-mr-widget-errors-with-external-services.yml b/changelogs/unreleased/33287-fix-mr-widget-errors-with-external-services.yml
new file mode 100644
index 00000000000..f0c76060781
--- /dev/null
+++ b/changelogs/unreleased/33287-fix-mr-widget-errors-with-external-services.yml
@@ -0,0 +1,5 @@
+---
+title: Fix errors thrown in merge request widget with external CI service/integration
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/34259-project-denial-of-service-via-gitmodules-fix.yml b/changelogs/unreleased/34259-project-denial-of-service-via-gitmodules-fix.yml
new file mode 100644
index 00000000000..8260f7fa4b2
--- /dev/null
+++ b/changelogs/unreleased/34259-project-denial-of-service-via-gitmodules-fix.yml
@@ -0,0 +1,5 @@
+---
+title: Fixes project denial of service via gitmodules using Extended ASCII.
+merge_request: 14301
+author:
+type: fixed
diff --git a/changelogs/unreleased/issue_32215.yml b/changelogs/unreleased/issue_32215.yml
new file mode 100644
index 00000000000..c608eb6dd28
--- /dev/null
+++ b/changelogs/unreleased/issue_32215.yml
@@ -0,0 +1,5 @@
+---
+title: Allow developer role to admin milestones
+merge_request:
+author:
+type: changed
diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb
index 5d106b5c075..bdc0f04b56b 100644
--- a/lib/gitlab/i18n.rb
+++ b/lib/gitlab/i18n.rb
@@ -17,7 +17,8 @@ module Gitlab
'it' => 'Italiano',
'uk' => 'Українська',
'ja' => '日本語',
- 'ko' => '한국어'
+ 'ko' => '한국어',
+ 'nl_NL' => 'Nederlands'
}.freeze
def available_locales
diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po
index fcd4aa29834..9d90f4ed5b1 100644
--- a/locale/bg/gitlab.po
+++ b/locale/bg/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:22-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Bulgarian\n"
"Language: bg_BG\n"
@@ -986,6 +986,24 @@ msgstr "Графика"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po
index 86deb620f0b..19961043ede 100644
--- a/locale/de/gitlab.po
+++ b/locale/de/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:22-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: German\n"
"Language: de_DE\n"
@@ -70,7 +70,7 @@ msgid "Account"
msgstr ""
msgid "Active"
-msgstr ""
+msgstr "Aktiv"
msgid "Activity"
msgstr ""
@@ -82,7 +82,7 @@ msgid "Add Contribution guide"
msgstr "Mitarbeitsanleitung hinzufügen"
msgid "Add License"
-msgstr ""
+msgstr "Lizenz hinzufügen"
msgid "Add an SSH key to your profile to pull or push via SSH."
msgstr "Füge einen SSH Schlüssel zu deinem Profil hinzu, um mittels SSH zu übertragen (push) oder abzurufen (pull)."
@@ -94,10 +94,10 @@ msgid "All"
msgstr "Alle"
msgid "Appearances"
-msgstr ""
+msgstr "Erscheinungsbild"
msgid "Applications"
-msgstr ""
+msgstr "Anwendungen"
msgid "Archived project! Repository is read-only"
msgstr "Archiviertes Projekt! Repository ist nicht änderbar."
@@ -213,10 +213,10 @@ msgid "CI / CD"
msgstr ""
msgid "CI configuration"
-msgstr ""
+msgstr "CI-Konfiguration"
msgid "Cancel"
-msgstr ""
+msgstr "Abbrechen"
msgid "Cancel edit"
msgstr "Bearbeitung abbrechen"
@@ -487,7 +487,7 @@ msgid "Edit Pipeline Schedule %{id}"
msgstr "Pipeline Zeitplan bearbeiten %{id}"
msgid "Emails"
-msgstr ""
+msgstr "E-Mails"
msgid "EventFilterBy|Filter by all"
msgstr "Filtere alle"
@@ -573,7 +573,7 @@ msgid "GoToYourFork|Fork"
msgstr "Ableger"
msgid "Group overview"
-msgstr ""
+msgstr "Gruppen-Übersicht"
msgid "Health Check"
msgstr "Systemzustand"
@@ -662,7 +662,7 @@ msgid "Leave project"
msgstr "Verlasse das Projekt"
msgid "License"
-msgstr ""
+msgstr "Lizenz"
msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most"
@@ -670,13 +670,13 @@ msgstr[0] "Limitiere die Anzeige auf höchstens %d Ereignis"
msgstr[1] "Limitiere die Anzeige auf höchstens %d Ereignisse"
msgid "Locked Files"
-msgstr ""
+msgstr "Gesperrte Dateien"
msgid "Median"
-msgstr ""
+msgstr "Median"
msgid "Members"
-msgstr ""
+msgstr "Mitglieder"
msgid "Merge Requests"
msgstr ""
@@ -795,7 +795,7 @@ msgid "NotificationLevel|Watch"
msgstr "Beobachten"
msgid "Notifications"
-msgstr ""
+msgstr "Benachrichtigungen"
msgid "OfSearchInADropdown|Filter"
msgstr "Filter"
@@ -807,13 +807,13 @@ msgid "Options"
msgstr "Optionen"
msgid "Overview"
-msgstr ""
+msgstr "Übersicht"
msgid "Owner"
msgstr "Besitzer"
msgid "Password"
-msgstr ""
+msgstr "Passwort"
msgid "Pipeline"
msgstr ""
@@ -986,6 +986,24 @@ msgstr "Diagramm"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr "Übertragungsereignisse"
diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po
index 8f25c893ecd..f9f61a109f6 100644
--- a/locale/eo/gitlab.po
+++ b/locale/eo/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:21-0400\n"
+"PO-Revision-Date: 2017-09-15 05:22-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Esperanto\n"
"Language: eo_UY\n"
@@ -986,6 +986,24 @@ msgstr "Grafeo"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po
index eee720d5ba2..ccf4b0abf9f 100644
--- a/locale/es/gitlab.po
+++ b/locale/es/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:19-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Spanish\n"
"Language: es_ES\n"
@@ -986,6 +986,24 @@ msgstr "Historial gráfico"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po
index 43e66d8dea4..c98156e026e 100644
--- a/locale/fr/gitlab.po
+++ b/locale/fr/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:22-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: French\n"
"Language: fr_FR\n"
@@ -986,6 +986,24 @@ msgstr "Graphique "
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po
index 46b3e12f97c..0249c4fe9eb 100644
--- a/locale/it/gitlab.po
+++ b/locale/it/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:20-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Italian\n"
"Language: it_IT\n"
@@ -986,6 +986,24 @@ msgstr "Grafico"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po
index bc25b69c80a..c66dd3c1b6b 100644
--- a/locale/ja/gitlab.po
+++ b/locale/ja/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:20-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Japanese\n"
"Language: ja_JP\n"
@@ -975,6 +975,24 @@ msgstr "ネットワークグラフ"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/ko/gitlab.po b/locale/ko/gitlab.po
index 4baefdb9a3e..bbf4aa15cd7 100644
--- a/locale/ko/gitlab.po
+++ b/locale/ko/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:19-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Korean\n"
"Language: ko_KR\n"
@@ -975,6 +975,24 @@ msgstr "그래프"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr "푸쉬 이벤트"
diff --git a/locale/nl_NL/gitlab.po b/locale/nl_NL/gitlab.po
new file mode 100644
index 00000000000..250d3bd413c
--- /dev/null
+++ b/locale/nl_NL/gitlab.po
@@ -0,0 +1,1474 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: gitlab-ee\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-09-06 08:32+0200\n"
+"PO-Revision-Date: 2017-09-15 05:20-0400\n"
+"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
+"Language-Team: Dutch\n"
+"Language: nl_NL\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: crowdin.com\n"
+"X-Crowdin-Project: gitlab-ee\n"
+"X-Crowdin-Language: nl\n"
+"X-Crowdin-File: /master/locale/gitlab.pot\n"
+
+msgid "%d commit"
+msgid_plural "%d commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%s additional commit has been omitted to prevent performance issues."
+msgid_plural "%s additional commits have been omitted to prevent performance issues."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%{commit_author_link} committed %{commit_timeago}"
+msgstr ""
+
+msgid "%{number_of_failures} of %{maximum_failures} failures. GitLab will allow access on the next attempt."
+msgstr ""
+
+msgid "%{number_of_failures} of %{maximum_failures} failures. GitLab will block access for %{number_of_seconds} seconds."
+msgstr ""
+
+msgid "%{number_of_failures} of %{maximum_failures} failures. GitLab will not retry automatically. Reset storage information when the problem is resolved."
+msgstr ""
+
+msgid "%{storage_name}: failed storage access attempt on host:"
+msgid_plural "%{storage_name}: %{failed_attempts} failed storage access attempts:"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "(checkout the %{link} for information on how to install it)."
+msgstr ""
+
+msgid "1 pipeline"
+msgid_plural "%d pipelines"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "A collection of graphs regarding Continuous Integration"
+msgstr ""
+
+msgid "About auto deploy"
+msgstr ""
+
+msgid "Abuse Reports"
+msgstr ""
+
+msgid "Access Tokens"
+msgstr ""
+
+msgid "Access to failing storages has been temporarily disabled to allow the mount to recover. Reset storage information after the issue has been resolved to allow access again."
+msgstr ""
+
+msgid "Account"
+msgstr ""
+
+msgid "Active"
+msgstr ""
+
+msgid "Activity"
+msgstr ""
+
+msgid "Add Changelog"
+msgstr ""
+
+msgid "Add Contribution guide"
+msgstr ""
+
+msgid "Add License"
+msgstr ""
+
+msgid "Add an SSH key to your profile to pull or push via SSH."
+msgstr ""
+
+msgid "Add new directory"
+msgstr ""
+
+msgid "All"
+msgstr ""
+
+msgid "Appearances"
+msgstr ""
+
+msgid "Applications"
+msgstr ""
+
+msgid "Archived project! Repository is read-only"
+msgstr ""
+
+msgid "Are you sure you want to delete this pipeline schedule?"
+msgstr ""
+
+msgid "Are you sure you want to discard your changes?"
+msgstr ""
+
+msgid "Are you sure you want to reset registration token?"
+msgstr ""
+
+msgid "Are you sure you want to reset the health check token?"
+msgstr ""
+
+msgid "Are you sure?"
+msgstr ""
+
+msgid "Attach a file by drag &amp; drop or %{upload_link}"
+msgstr ""
+
+msgid "Authentication log"
+msgstr ""
+
+msgid "Billing"
+msgstr ""
+
+msgid "BillingPlans|%{group_name} is currently on the %{plan_link} plan."
+msgstr ""
+
+msgid "BillingPlans|Automatic downgrade and upgrade to some plans is currently not available."
+msgstr ""
+
+msgid "BillingPlans|Current plan"
+msgstr ""
+
+msgid "BillingPlans|Customer Support"
+msgstr ""
+
+msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}."
+msgstr ""
+
+msgid "BillingPlans|Manage plan"
+msgstr ""
+
+msgid "BillingPlans|Please contact %{customer_support_link} in that case."
+msgstr ""
+
+msgid "BillingPlans|See all %{plan_name} features"
+msgstr ""
+
+msgid "BillingPlans|This group uses the plan associated with its parent group."
+msgstr ""
+
+msgid "BillingPlans|To manage the plan for this group, visit the billing section of %{parent_billing_page_link}."
+msgstr ""
+
+msgid "BillingPlans|Upgrade"
+msgstr ""
+
+msgid "BillingPlans|You are currently on the %{plan_link} plan."
+msgstr ""
+
+msgid "BillingPlans|frequently asked questions"
+msgstr ""
+
+msgid "BillingPlans|monthly"
+msgstr ""
+
+msgid "BillingPlans|paid annually at %{price_per_year}"
+msgstr ""
+
+msgid "BillingPlans|per user"
+msgstr ""
+
+msgid "Billinglans|Downgrade"
+msgstr ""
+
+msgid "Branch"
+msgid_plural "Branches"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
+msgstr ""
+
+msgid "BranchSwitcherPlaceholder|Search branches"
+msgstr ""
+
+msgid "BranchSwitcherTitle|Switch branch"
+msgstr ""
+
+msgid "Branches"
+msgstr ""
+
+msgid "Browse Directory"
+msgstr ""
+
+msgid "Browse File"
+msgstr ""
+
+msgid "Browse Files"
+msgstr ""
+
+msgid "Browse files"
+msgstr ""
+
+msgid "ByAuthor|by"
+msgstr ""
+
+msgid "CI / CD"
+msgstr ""
+
+msgid "CI configuration"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Cancel edit"
+msgstr ""
+
+msgid "ChangeTypeActionLabel|Pick into branch"
+msgstr ""
+
+msgid "ChangeTypeActionLabel|Revert in branch"
+msgstr ""
+
+msgid "ChangeTypeAction|Cherry-pick"
+msgstr ""
+
+msgid "ChangeTypeAction|Revert"
+msgstr ""
+
+msgid "Changelog"
+msgstr ""
+
+msgid "Charts"
+msgstr ""
+
+msgid "Chat"
+msgstr ""
+
+msgid "Cherry-pick this commit"
+msgstr ""
+
+msgid "Cherry-pick this merge request"
+msgstr ""
+
+msgid "CiStatusLabel|canceled"
+msgstr ""
+
+msgid "CiStatusLabel|created"
+msgstr ""
+
+msgid "CiStatusLabel|failed"
+msgstr ""
+
+msgid "CiStatusLabel|manual action"
+msgstr ""
+
+msgid "CiStatusLabel|passed"
+msgstr ""
+
+msgid "CiStatusLabel|passed with warnings"
+msgstr ""
+
+msgid "CiStatusLabel|pending"
+msgstr ""
+
+msgid "CiStatusLabel|skipped"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for manual action"
+msgstr ""
+
+msgid "CiStatusText|blocked"
+msgstr ""
+
+msgid "CiStatusText|canceled"
+msgstr ""
+
+msgid "CiStatusText|created"
+msgstr ""
+
+msgid "CiStatusText|failed"
+msgstr ""
+
+msgid "CiStatusText|manual"
+msgstr ""
+
+msgid "CiStatusText|passed"
+msgstr ""
+
+msgid "CiStatusText|pending"
+msgstr ""
+
+msgid "CiStatusText|skipped"
+msgstr ""
+
+msgid "CiStatus|running"
+msgstr ""
+
+msgid "Comments"
+msgstr ""
+
+msgid "Commit"
+msgid_plural "Commits"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Commit duration in minutes for last 30 commits"
+msgstr ""
+
+msgid "Commit message"
+msgstr ""
+
+msgid "CommitBoxTitle|Commit"
+msgstr ""
+
+msgid "CommitMessage|Add %{file_name}"
+msgstr ""
+
+msgid "Commits"
+msgstr ""
+
+msgid "Commits feed"
+msgstr ""
+
+msgid "Commits|History"
+msgstr ""
+
+msgid "Committed by"
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Container Registry"
+msgstr ""
+
+msgid "Contribution guide"
+msgstr ""
+
+msgid "Contributors"
+msgstr ""
+
+msgid "Copy SSH public key to clipboard"
+msgstr ""
+
+msgid "Copy URL to clipboard"
+msgstr ""
+
+msgid "Copy commit SHA to clipboard"
+msgstr ""
+
+msgid "Create New Directory"
+msgstr ""
+
+msgid "Create a new branch"
+msgstr ""
+
+msgid "Create a personal access token on your account to pull or push via %{protocol}."
+msgstr ""
+
+msgid "Create directory"
+msgstr ""
+
+msgid "Create empty bare repository"
+msgstr ""
+
+msgid "Create merge request"
+msgstr ""
+
+msgid "Create new..."
+msgstr ""
+
+msgid "CreateNewFork|Fork"
+msgstr ""
+
+msgid "CreateTag|Tag"
+msgstr ""
+
+msgid "CreateTokenToCloneLink|create a personal access token"
+msgstr ""
+
+msgid "Cron Timezone"
+msgstr ""
+
+msgid "Cron syntax"
+msgstr ""
+
+msgid "Custom notification events"
+msgstr ""
+
+msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
+msgstr ""
+
+msgid "Cycle Analytics"
+msgstr ""
+
+msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
+msgstr ""
+
+msgid "CycleAnalyticsStage|Code"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Issue"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Plan"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Production"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Review"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Staging"
+msgstr ""
+
+msgid "CycleAnalyticsStage|Test"
+msgstr ""
+
+msgid "Define a custom pattern with cron syntax"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Deploy"
+msgid_plural "Deploys"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Deploy Keys"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Details"
+msgstr ""
+
+msgid "Directory name"
+msgstr ""
+
+msgid "Discard changes"
+msgstr ""
+
+msgid "Don't show again"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "Download tar"
+msgstr ""
+
+msgid "Download tar.bz2"
+msgstr ""
+
+msgid "Download tar.gz"
+msgstr ""
+
+msgid "Download zip"
+msgstr "Download zip"
+
+msgid "DownloadArtifacts|Download"
+msgstr ""
+
+msgid "DownloadCommit|Email Patches"
+msgstr ""
+
+msgid "DownloadCommit|Plain Diff"
+msgstr ""
+
+msgid "DownloadSource|Download"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Edit Pipeline Schedule %{id}"
+msgstr ""
+
+msgid "Emails"
+msgstr ""
+
+msgid "EventFilterBy|Filter by all"
+msgstr ""
+
+msgid "EventFilterBy|Filter by comments"
+msgstr ""
+
+msgid "EventFilterBy|Filter by issue events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by merge events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by push events"
+msgstr ""
+
+msgid "EventFilterBy|Filter by team"
+msgstr ""
+
+msgid "Every day (at 4:00am)"
+msgstr ""
+
+msgid "Every month (on the 1st at 4:00am)"
+msgstr ""
+
+msgid "Every week (Sundays at 4:00am)"
+msgstr ""
+
+msgid "Failed to change the owner"
+msgstr ""
+
+msgid "Failed to remove the pipeline schedule"
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Filter by commit message"
+msgstr ""
+
+msgid "Find by path"
+msgstr ""
+
+msgid "Find file"
+msgstr ""
+
+msgid "FirstPushedBy|First"
+msgstr ""
+
+msgid "FirstPushedBy|pushed by"
+msgstr ""
+
+msgid "Fork"
+msgid_plural "Forks"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ForkedFromProjectPath|Forked from"
+msgstr ""
+
+msgid "From issue creation until deploy to production"
+msgstr ""
+
+msgid "From merge request merge until deploy to production"
+msgstr ""
+
+msgid "GPG Keys"
+msgstr ""
+
+msgid "Geo Nodes"
+msgstr ""
+
+msgid "Git storage health information has been reset"
+msgstr ""
+
+msgid "GitLab Runner section"
+msgstr ""
+
+msgid "Go to your fork"
+msgstr ""
+
+msgid "GoToYourFork|Fork"
+msgstr ""
+
+msgid "Group overview"
+msgstr ""
+
+msgid "Health Check"
+msgstr ""
+
+msgid "Health information can be retrieved from the following endpoints. More information is available"
+msgstr ""
+
+msgid "HealthCheck|Access token is"
+msgstr ""
+
+msgid "HealthCheck|Healthy"
+msgstr ""
+
+msgid "HealthCheck|No Health Problems Detected"
+msgstr ""
+
+msgid "HealthCheck|Unhealthy"
+msgstr ""
+
+msgid "Home"
+msgstr ""
+
+msgid "Hooks"
+msgstr ""
+
+msgid "Housekeeping successfully started"
+msgstr ""
+
+msgid "Import repository"
+msgstr ""
+
+msgid "Install a Runner compatible with GitLab CI"
+msgstr ""
+
+msgid "Interval Pattern"
+msgstr ""
+
+msgid "Introducing Cycle Analytics"
+msgstr ""
+
+msgid "Issue events"
+msgstr ""
+
+msgid "Issues"
+msgstr ""
+
+msgid "LFSStatus|Disabled"
+msgstr ""
+
+msgid "LFSStatus|Enabled"
+msgstr ""
+
+msgid "Labels"
+msgstr ""
+
+msgid "Last %d day"
+msgid_plural "Last %d days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Last Pipeline"
+msgstr ""
+
+msgid "Last Update"
+msgstr ""
+
+msgid "Last commit"
+msgstr ""
+
+msgid "LastPushEvent|You pushed to"
+msgstr ""
+
+msgid "LastPushEvent|at"
+msgstr ""
+
+msgid "Learn more in the"
+msgstr ""
+
+msgid "Learn more in the|pipeline schedules documentation"
+msgstr ""
+
+msgid "Leave group"
+msgstr ""
+
+msgid "Leave project"
+msgstr ""
+
+msgid "License"
+msgstr ""
+
+msgid "Limited to showing %d event at most"
+msgid_plural "Limited to showing %d events at most"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Locked Files"
+msgstr ""
+
+msgid "Median"
+msgstr ""
+
+msgid "Members"
+msgstr ""
+
+msgid "Merge Requests"
+msgstr ""
+
+msgid "Merge events"
+msgstr ""
+
+msgid "Messages"
+msgstr ""
+
+msgid "MissingSSHKeyWarningLink|add an SSH key"
+msgstr ""
+
+msgid "Monitoring"
+msgstr ""
+
+msgid "More information is available|here"
+msgstr ""
+
+msgid "New Issue"
+msgid_plural "New Issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "New Pipeline Schedule"
+msgstr ""
+
+msgid "New branch"
+msgstr ""
+
+msgid "New directory"
+msgstr ""
+
+msgid "New file"
+msgstr ""
+
+msgid "New issue"
+msgstr ""
+
+msgid "New merge request"
+msgstr ""
+
+msgid "New schedule"
+msgstr ""
+
+msgid "New snippet"
+msgstr ""
+
+msgid "New tag"
+msgstr ""
+
+msgid "No repository"
+msgstr ""
+
+msgid "No schedules"
+msgstr ""
+
+msgid "Not available"
+msgstr ""
+
+msgid "Not enough data"
+msgstr ""
+
+msgid "Notification events"
+msgstr ""
+
+msgid "NotificationEvent|Close issue"
+msgstr ""
+
+msgid "NotificationEvent|Close merge request"
+msgstr ""
+
+msgid "NotificationEvent|Failed pipeline"
+msgstr ""
+
+msgid "NotificationEvent|Merge merge request"
+msgstr ""
+
+msgid "NotificationEvent|New issue"
+msgstr ""
+
+msgid "NotificationEvent|New merge request"
+msgstr ""
+
+msgid "NotificationEvent|New note"
+msgstr ""
+
+msgid "NotificationEvent|Reassign issue"
+msgstr ""
+
+msgid "NotificationEvent|Reassign merge request"
+msgstr ""
+
+msgid "NotificationEvent|Reopen issue"
+msgstr ""
+
+msgid "NotificationEvent|Successful pipeline"
+msgstr ""
+
+msgid "NotificationLevel|Custom"
+msgstr ""
+
+msgid "NotificationLevel|Disabled"
+msgstr ""
+
+msgid "NotificationLevel|Global"
+msgstr ""
+
+msgid "NotificationLevel|On mention"
+msgstr ""
+
+msgid "NotificationLevel|Participate"
+msgstr ""
+
+msgid "NotificationLevel|Watch"
+msgstr ""
+
+msgid "Notifications"
+msgstr ""
+
+msgid "OfSearchInADropdown|Filter"
+msgstr ""
+
+msgid "OpenedNDaysAgo|Opened"
+msgstr ""
+
+msgid "Options"
+msgstr ""
+
+msgid "Overview"
+msgstr ""
+
+msgid "Owner"
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "Pipeline"
+msgstr ""
+
+msgid "Pipeline Health"
+msgstr ""
+
+msgid "Pipeline Schedule"
+msgstr ""
+
+msgid "Pipeline Schedules"
+msgstr ""
+
+msgid "Pipeline quota"
+msgstr ""
+
+msgid "PipelineCharts|Failed:"
+msgstr ""
+
+msgid "PipelineCharts|Overall statistics"
+msgstr ""
+
+msgid "PipelineCharts|Success ratio:"
+msgstr ""
+
+msgid "PipelineCharts|Successful:"
+msgstr ""
+
+msgid "PipelineCharts|Total:"
+msgstr ""
+
+msgid "PipelineSchedules|Activated"
+msgstr ""
+
+msgid "PipelineSchedules|Active"
+msgstr ""
+
+msgid "PipelineSchedules|All"
+msgstr ""
+
+msgid "PipelineSchedules|Inactive"
+msgstr ""
+
+msgid "PipelineSchedules|Input variable key"
+msgstr ""
+
+msgid "PipelineSchedules|Input variable value"
+msgstr ""
+
+msgid "PipelineSchedules|Next Run"
+msgstr ""
+
+msgid "PipelineSchedules|None"
+msgstr ""
+
+msgid "PipelineSchedules|Provide a short description for this pipeline"
+msgstr ""
+
+msgid "PipelineSchedules|Remove variable row"
+msgstr ""
+
+msgid "PipelineSchedules|Take ownership"
+msgstr ""
+
+msgid "PipelineSchedules|Target"
+msgstr ""
+
+msgid "PipelineSchedules|Variables"
+msgstr ""
+
+msgid "PipelineSheduleIntervalPattern|Custom"
+msgstr ""
+
+msgid "Pipelines"
+msgstr ""
+
+msgid "Pipelines charts"
+msgstr ""
+
+msgid "Pipelines for last month"
+msgstr ""
+
+msgid "Pipelines for last week"
+msgstr ""
+
+msgid "Pipelines for last year"
+msgstr ""
+
+msgid "Pipeline|all"
+msgstr ""
+
+msgid "Pipeline|success"
+msgstr ""
+
+msgid "Pipeline|with stage"
+msgstr ""
+
+msgid "Pipeline|with stages"
+msgstr ""
+
+msgid "Preferences"
+msgstr ""
+
+msgid "Profile Settings"
+msgstr ""
+
+msgid "Project"
+msgstr ""
+
+msgid "Project '%{project_name}' queued for deletion."
+msgstr ""
+
+msgid "Project '%{project_name}' was successfully created."
+msgstr ""
+
+msgid "Project '%{project_name}' was successfully updated."
+msgstr ""
+
+msgid "Project '%{project_name}' will be deleted."
+msgstr ""
+
+msgid "Project access must be granted explicitly to each user."
+msgstr ""
+
+msgid "Project details"
+msgstr ""
+
+msgid "Project export could not be deleted."
+msgstr ""
+
+msgid "Project export has been deleted."
+msgstr ""
+
+msgid "Project export link has expired. Please generate a new export from your project settings."
+msgstr ""
+
+msgid "Project export started. A download link will be sent by email."
+msgstr ""
+
+msgid "Project home"
+msgstr ""
+
+msgid "Project overview"
+msgstr ""
+
+msgid "ProjectActivityRSS|Subscribe"
+msgstr ""
+
+msgid "ProjectFeature|Disabled"
+msgstr ""
+
+msgid "ProjectFeature|Everyone with access"
+msgstr ""
+
+msgid "ProjectFeature|Only team members"
+msgstr ""
+
+msgid "ProjectFileTree|Name"
+msgstr ""
+
+msgid "ProjectLastActivity|Never"
+msgstr ""
+
+msgid "ProjectLifecycle|Stage"
+msgstr ""
+
+msgid "ProjectNetworkGraph|Graph"
+msgstr ""
+
+msgid "Push Rules"
+msgstr ""
+
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
+msgid "Push events"
+msgstr ""
+
+msgid "Read more"
+msgstr ""
+
+msgid "Readme"
+msgstr ""
+
+msgid "RefSwitcher|Branches"
+msgstr ""
+
+msgid "RefSwitcher|Tags"
+msgstr ""
+
+msgid "Related Commits"
+msgstr ""
+
+msgid "Related Deployed Jobs"
+msgstr ""
+
+msgid "Related Issues"
+msgstr ""
+
+msgid "Related Jobs"
+msgstr ""
+
+msgid "Related Merge Requests"
+msgstr ""
+
+msgid "Related Merged Requests"
+msgstr ""
+
+msgid "Remind later"
+msgstr ""
+
+msgid "Remove project"
+msgstr ""
+
+msgid "Repository"
+msgstr ""
+
+msgid "Request Access"
+msgstr ""
+
+msgid "Reset git storage health information"
+msgstr ""
+
+msgid "Reset health check access token"
+msgstr ""
+
+msgid "Reset runners registration token"
+msgstr ""
+
+msgid "Revert this commit"
+msgstr ""
+
+msgid "Revert this merge request"
+msgstr ""
+
+msgid "SSH Keys"
+msgstr ""
+
+msgid "Save pipeline schedule"
+msgstr ""
+
+msgid "Schedule a new pipeline"
+msgstr ""
+
+msgid "Scheduling Pipelines"
+msgstr ""
+
+msgid "Search branches and tags"
+msgstr ""
+
+msgid "Select Archive Format"
+msgstr ""
+
+msgid "Select a timezone"
+msgstr ""
+
+msgid "Select existing branch"
+msgstr ""
+
+msgid "Select target branch"
+msgstr ""
+
+msgid "Service Templates"
+msgstr ""
+
+msgid "Set a password on your account to pull or push via %{protocol}."
+msgstr ""
+
+msgid "Set up CI"
+msgstr ""
+
+msgid "Set up Koding"
+msgstr ""
+
+msgid "Set up auto deploy"
+msgstr ""
+
+msgid "SetPasswordToCloneLink|set a password"
+msgstr ""
+
+msgid "Settings"
+msgstr ""
+
+msgid "Showing %d event"
+msgid_plural "Showing %d events"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Snippets"
+msgstr ""
+
+msgid "Source code"
+msgstr ""
+
+msgid "Spam Logs"
+msgstr ""
+
+msgid "Specify the following URL during the Runner setup:"
+msgstr ""
+
+msgid "StarProject|Star"
+msgstr ""
+
+msgid "Start a %{new_merge_request} with these changes"
+msgstr ""
+
+msgid "Start the Runner!"
+msgstr ""
+
+msgid "Switch branch/tag"
+msgstr ""
+
+msgid "Tag"
+msgid_plural "Tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Tags"
+msgstr ""
+
+msgid "Target Branch"
+msgstr ""
+
+msgid "Team"
+msgstr ""
+
+msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
+msgstr ""
+
+msgid "The collection of events added to the data gathered for that stage."
+msgstr ""
+
+msgid "The fork relationship has been removed."
+msgstr ""
+
+msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
+msgstr ""
+
+msgid "The phase of the development lifecycle."
+msgstr ""
+
+msgid "The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user."
+msgstr ""
+
+msgid "The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit."
+msgstr ""
+
+msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
+msgstr ""
+
+msgid "The project can be accessed by any logged in user."
+msgstr ""
+
+msgid "The project can be accessed without any authentication."
+msgstr ""
+
+msgid "The repository for this project does not exist."
+msgstr ""
+
+msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
+msgstr ""
+
+msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
+msgstr ""
+
+msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
+msgstr ""
+
+msgid "The time taken by each data entry gathered by that stage."
+msgstr ""
+
+msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
+msgstr ""
+
+msgid "There are problems accessing Git storage: "
+msgstr ""
+
+msgid "This means you can not push code until you create an empty repository or import existing one."
+msgstr ""
+
+msgid "Time before an issue gets scheduled"
+msgstr ""
+
+msgid "Time before an issue starts implementation"
+msgstr ""
+
+msgid "Time between merge request creation and merge/close"
+msgstr ""
+
+msgid "Time until first merge request"
+msgstr ""
+
+msgid "Timeago|%s days ago"
+msgstr ""
+
+msgid "Timeago|%s days remaining"
+msgstr ""
+
+msgid "Timeago|%s hours remaining"
+msgstr ""
+
+msgid "Timeago|%s minutes ago"
+msgstr ""
+
+msgid "Timeago|%s minutes remaining"
+msgstr ""
+
+msgid "Timeago|%s months ago"
+msgstr ""
+
+msgid "Timeago|%s months remaining"
+msgstr ""
+
+msgid "Timeago|%s seconds remaining"
+msgstr ""
+
+msgid "Timeago|%s weeks ago"
+msgstr ""
+
+msgid "Timeago|%s weeks remaining"
+msgstr ""
+
+msgid "Timeago|%s years ago"
+msgstr ""
+
+msgid "Timeago|%s years remaining"
+msgstr ""
+
+msgid "Timeago|1 day remaining"
+msgstr ""
+
+msgid "Timeago|1 hour remaining"
+msgstr ""
+
+msgid "Timeago|1 minute remaining"
+msgstr ""
+
+msgid "Timeago|1 month remaining"
+msgstr ""
+
+msgid "Timeago|1 week remaining"
+msgstr ""
+
+msgid "Timeago|1 year remaining"
+msgstr ""
+
+msgid "Timeago|Past due"
+msgstr ""
+
+msgid "Timeago|a day ago"
+msgstr ""
+
+msgid "Timeago|a month ago"
+msgstr ""
+
+msgid "Timeago|a week ago"
+msgstr ""
+
+msgid "Timeago|a while"
+msgstr ""
+
+msgid "Timeago|a year ago"
+msgstr ""
+
+msgid "Timeago|about %s hours ago"
+msgstr ""
+
+msgid "Timeago|about a minute ago"
+msgstr ""
+
+msgid "Timeago|about an hour ago"
+msgstr ""
+
+msgid "Timeago|in %s days"
+msgstr ""
+
+msgid "Timeago|in %s hours"
+msgstr ""
+
+msgid "Timeago|in %s minutes"
+msgstr ""
+
+msgid "Timeago|in %s months"
+msgstr ""
+
+msgid "Timeago|in %s seconds"
+msgstr ""
+
+msgid "Timeago|in %s weeks"
+msgstr ""
+
+msgid "Timeago|in %s years"
+msgstr ""
+
+msgid "Timeago|in 1 day"
+msgstr ""
+
+msgid "Timeago|in 1 hour"
+msgstr ""
+
+msgid "Timeago|in 1 minute"
+msgstr ""
+
+msgid "Timeago|in 1 month"
+msgstr ""
+
+msgid "Timeago|in 1 week"
+msgstr ""
+
+msgid "Timeago|in 1 year"
+msgstr ""
+
+msgid "Timeago|less than a minute ago"
+msgstr ""
+
+msgid "Time|hr"
+msgid_plural "Time|hrs"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Time|min"
+msgid_plural "Time|mins"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Time|s"
+msgstr ""
+
+msgid "Total Time"
+msgstr ""
+
+msgid "Total test time for all commits/merges"
+msgstr ""
+
+msgid "Unstar"
+msgstr ""
+
+msgid "Upload New File"
+msgstr ""
+
+msgid "Upload file"
+msgstr ""
+
+msgid "UploadLink|click to upload"
+msgstr ""
+
+msgid "Use the following registration token during setup:"
+msgstr ""
+
+msgid "Use your global notification setting"
+msgstr ""
+
+msgid "View open merge request"
+msgstr ""
+
+msgid "VisibilityLevel|Internal"
+msgstr ""
+
+msgid "VisibilityLevel|Private"
+msgstr ""
+
+msgid "VisibilityLevel|Public"
+msgstr ""
+
+msgid "VisibilityLevel|Unknown"
+msgstr ""
+
+msgid "Want to see the data? Please ask an administrator for access."
+msgstr ""
+
+msgid "We don't have enough data to show this stage."
+msgstr ""
+
+msgid "Wiki"
+msgstr ""
+
+msgid "Withdraw Access Request"
+msgstr ""
+
+msgid "You are going to remove %{group_name}. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to remove %{project_name_with_namespace}. Removed project CANNOT be restored! Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You can only add files when you are on a branch"
+msgstr ""
+
+msgid "You have reached your project limit"
+msgstr ""
+
+msgid "You must sign in to star a project"
+msgstr ""
+
+msgid "You need permission."
+msgstr ""
+
+msgid "You will not get any notifications via email"
+msgstr ""
+
+msgid "You will only receive notifications for the events you choose"
+msgstr ""
+
+msgid "You will only receive notifications for threads you have participated in"
+msgstr ""
+
+msgid "You will receive notifications for any activity"
+msgstr ""
+
+msgid "You will receive notifications only for comments in which you were @mentioned"
+msgstr ""
+
+msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
+msgstr ""
+
+msgid "You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile"
+msgstr ""
+
+msgid "Your name"
+msgstr ""
+
+msgid "day"
+msgid_plural "days"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "new merge request"
+msgstr ""
+
+msgid "notification emails"
+msgstr ""
+
+msgid "parent"
+msgid_plural "parents"
+msgstr[0] ""
+msgstr[1] ""
+
diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po
index 88ca25dbb3b..5469f77d950 100644
--- a/locale/pt_BR/gitlab.po
+++ b/locale/pt_BR/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:18-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Portuguese, Brazilian\n"
"Language: pt_BR\n"
@@ -986,6 +986,24 @@ msgstr "Árvore"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po
index 96e6c8a8d3f..808bc9dedce 100644
--- a/locale/ru/gitlab.po
+++ b/locale/ru/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:19-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Russian\n"
"Language: ru_RU\n"
@@ -997,6 +997,24 @@ msgstr "Граф"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po
index 4d24140f3dc..1dc42901daf 100644
--- a/locale/uk/gitlab.po
+++ b/locale/uk/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:20-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Ukrainian\n"
"Language: uk_UA\n"
@@ -997,6 +997,24 @@ msgstr "Історія"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr ""
diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po
index 47de28209df..d6f756e813f 100644
--- a/locale/zh_CN/gitlab.po
+++ b/locale/zh_CN/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:21-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"
@@ -54,16 +54,16 @@ msgid "About auto deploy"
msgstr "关于自动部署"
msgid "Abuse Reports"
-msgstr ""
+msgstr "滥用报告"
msgid "Access Tokens"
-msgstr ""
+msgstr "访问令牌"
msgid "Access to failing storages has been temporarily disabled to allow the mount to recover. Reset storage information after the issue has been resolved to allow access again."
msgstr "为方便修复挂载问题,访问故障存储已被暂时禁用。在问题解决后请重置存储健康信息,以允许再次访问。"
msgid "Account"
-msgstr ""
+msgstr "帐号"
msgid "Active"
msgstr "启用"
@@ -90,10 +90,10 @@ msgid "All"
msgstr "全部"
msgid "Appearances"
-msgstr ""
+msgstr "外观样式"
msgid "Applications"
-msgstr ""
+msgstr "应用程序"
msgid "Archived project! Repository is read-only"
msgstr "项目已归档!存储库为只读状态"
@@ -117,61 +117,61 @@ msgid "Attach a file by drag &amp; drop or %{upload_link}"
msgstr "拖放文件到此处或者 %{upload_link}"
msgid "Authentication log"
-msgstr ""
+msgstr "认证日志"
msgid "Billing"
-msgstr ""
+msgstr "账单"
msgid "BillingPlans|%{group_name} is currently on the %{plan_link} plan."
-msgstr ""
+msgstr "%{group_name} 目前正在使用 %{plan_link} 方案。"
msgid "BillingPlans|Automatic downgrade and upgrade to some plans is currently not available."
-msgstr ""
+msgstr "当某些方案当前不可用时自动降级和升级。"
msgid "BillingPlans|Current plan"
-msgstr ""
+msgstr "当前方案"
msgid "BillingPlans|Customer Support"
-msgstr ""
+msgstr "客户支持"
msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}."
-msgstr ""
+msgstr "通过阅读%{faq_link} 了解关于每个方案的更多信息。"
msgid "BillingPlans|Manage plan"
-msgstr ""
+msgstr "管理方案"
msgid "BillingPlans|Please contact %{customer_support_link} in that case."
-msgstr ""
+msgstr "在这种情况下,请联系 %{customer_support_link}。"
msgid "BillingPlans|See all %{plan_name} features"
-msgstr ""
+msgstr "查看 %{plan_name} 的所有功能"
msgid "BillingPlans|This group uses the plan associated with its parent group."
-msgstr ""
+msgstr "该群组使用与它的父团队相关联的计划。"
msgid "BillingPlans|To manage the plan for this group, visit the billing section of %{parent_billing_page_link}."
-msgstr ""
+msgstr "请访问 %{parent_billing_page_link} 的计费方案部分来管理该团队的计费方案,。"
msgid "BillingPlans|Upgrade"
-msgstr ""
+msgstr "升级"
msgid "BillingPlans|You are currently on the %{plan_link} plan."
-msgstr ""
+msgstr "你目前正在使用 %{plan_link} 方案。"
msgid "BillingPlans|frequently asked questions"
-msgstr ""
+msgstr "常见问题"
msgid "BillingPlans|monthly"
-msgstr ""
+msgstr "每月"
msgid "BillingPlans|paid annually at %{price_per_year}"
-msgstr ""
+msgstr "每年支付 %{price_per_year}"
msgid "BillingPlans|per user"
-msgstr ""
+msgstr "每个用户"
msgid "Billinglans|Downgrade"
-msgstr ""
+msgstr "降级"
msgid "Branch"
msgid_plural "Branches"
@@ -205,7 +205,7 @@ msgid "ByAuthor|by"
msgstr "作者:"
msgid "CI / CD"
-msgstr ""
+msgstr "CI / CD"
msgid "CI configuration"
msgstr "CI 配置"
@@ -235,7 +235,7 @@ msgid "Charts"
msgstr "统计图"
msgid "Chat"
-msgstr ""
+msgstr "交流"
msgid "Cherry-pick this commit"
msgstr "优选此提交"
@@ -332,7 +332,7 @@ msgid "Compare"
msgstr "比较"
msgid "Container Registry"
-msgstr ""
+msgstr "容器注册表"
msgid "Contribution guide"
msgstr "贡献指南"
@@ -341,7 +341,7 @@ msgid "Contributors"
msgstr "贡献者"
msgid "Copy SSH public key to clipboard"
-msgstr ""
+msgstr "将 SSH 公钥复制到剪贴板"
msgid "Copy URL to clipboard"
msgstr "复制 URL 到剪贴板"
@@ -429,7 +429,7 @@ msgid_plural "Deploys"
msgstr[0] "部署"
msgid "Deploy Keys"
-msgstr ""
+msgstr "部署密钥"
msgid "Description"
msgstr "描述"
@@ -480,7 +480,7 @@ msgid "Edit Pipeline Schedule %{id}"
msgstr "编辑 %{id} 流水线计划"
msgid "Emails"
-msgstr ""
+msgstr "电子邮件"
msgid "EventFilterBy|Filter by all"
msgstr "全部"
@@ -547,10 +547,10 @@ msgid "From merge request merge until deploy to production"
msgstr "从合并请求被合并后到部署至生产环境"
msgid "GPG Keys"
-msgstr ""
+msgstr "GPG 密钥"
msgid "Geo Nodes"
-msgstr ""
+msgstr "Geo 节点"
msgid "Git storage health information has been reset"
msgstr "Git 存储健康信息已重置"
@@ -565,7 +565,7 @@ msgid "GoToYourFork|Fork"
msgstr "跳转到派生项目"
msgid "Group overview"
-msgstr ""
+msgstr "群组概览"
msgid "Health Check"
msgstr "健康检查"
@@ -589,7 +589,7 @@ msgid "Home"
msgstr "首页"
msgid "Hooks"
-msgstr ""
+msgstr "钩子"
msgid "Housekeeping successfully started"
msgstr "已开始维护"
@@ -610,7 +610,7 @@ msgid "Issue events"
msgstr "议题事件"
msgid "Issues"
-msgstr ""
+msgstr "议题"
msgid "LFSStatus|Disabled"
msgstr "停用"
@@ -619,7 +619,7 @@ msgid "LFSStatus|Enabled"
msgstr "启用"
msgid "Labels"
-msgstr ""
+msgstr "标签"
msgid "Last %d day"
msgid_plural "Last %d days"
@@ -653,35 +653,35 @@ msgid "Leave project"
msgstr "退出项目"
msgid "License"
-msgstr ""
+msgstr "许可"
msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most"
msgstr[0] "最多显示 %d 个事件"
msgid "Locked Files"
-msgstr ""
+msgstr "锁定的文件"
msgid "Median"
msgstr "中位数"
msgid "Members"
-msgstr ""
+msgstr "成员"
msgid "Merge Requests"
-msgstr ""
+msgstr "合并请求"
msgid "Merge events"
msgstr "合并事件"
msgid "Messages"
-msgstr ""
+msgstr "消息"
msgid "MissingSSHKeyWarningLink|add an SSH key"
msgstr "新建 SSH 公钥"
msgid "Monitoring"
-msgstr ""
+msgstr "监控"
msgid "More information is available|here"
msgstr "帮助文档"
@@ -784,7 +784,7 @@ msgid "NotificationLevel|Watch"
msgstr "关注"
msgid "Notifications"
-msgstr ""
+msgstr "通知"
msgid "OfSearchInADropdown|Filter"
msgstr "筛选"
@@ -796,13 +796,13 @@ msgid "Options"
msgstr "操作"
msgid "Overview"
-msgstr ""
+msgstr "概览"
msgid "Owner"
msgstr "所有者"
msgid "Password"
-msgstr ""
+msgstr "密码"
msgid "Pipeline"
msgstr "流水线"
@@ -817,7 +817,7 @@ msgid "Pipeline Schedules"
msgstr "流水线计划"
msgid "Pipeline quota"
-msgstr ""
+msgstr "流水线配额"
msgid "PipelineCharts|Failed:"
msgstr "失败:"
@@ -883,13 +883,13 @@ msgid "Pipelines charts"
msgstr "流水线统计图"
msgid "Pipelines for last month"
-msgstr ""
+msgstr "上个月的流水线"
msgid "Pipelines for last week"
-msgstr ""
+msgstr "上周的流水线"
msgid "Pipelines for last year"
-msgstr ""
+msgstr "去年的流水线"
msgid "Pipeline|all"
msgstr "所有"
@@ -904,10 +904,10 @@ msgid "Pipeline|with stages"
msgstr "于阶段"
msgid "Preferences"
-msgstr ""
+msgstr "偏好设置"
msgid "Profile Settings"
-msgstr ""
+msgstr "账户设置"
msgid "Project"
msgstr "项目"
@@ -946,7 +946,7 @@ msgid "Project home"
msgstr "项目首页"
msgid "Project overview"
-msgstr ""
+msgstr "项目概览"
msgid "ProjectActivityRSS|Subscribe"
msgstr "订阅"
@@ -973,6 +973,24 @@ msgid "ProjectNetworkGraph|Graph"
msgstr "分支图"
msgid "Push Rules"
+msgstr "推送规则"
+
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
msgstr ""
msgid "Push events"
@@ -1036,7 +1054,7 @@ msgid "Revert this merge request"
msgstr "还原此合并请求"
msgid "SSH Keys"
-msgstr ""
+msgstr "SSH 密钥"
msgid "Save pipeline schedule"
msgstr "保存流水线计划"
@@ -1063,7 +1081,7 @@ msgid "Select target branch"
msgstr "选择目标分支"
msgid "Service Templates"
-msgstr ""
+msgstr "服务模板"
msgid "Set a password on your account to pull or push via %{protocol}."
msgstr "为账号创建一个用于推送或拉取的 %{protocol} 密码。"
@@ -1081,20 +1099,20 @@ msgid "SetPasswordToCloneLink|set a password"
msgstr "设置密码"
msgid "Settings"
-msgstr ""
+msgstr "设置"
msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] "显示 %d 个事件"
msgid "Snippets"
-msgstr ""
+msgstr "代码片段"
msgid "Source code"
msgstr "源代码"
msgid "Spam Logs"
-msgstr ""
+msgstr "垃圾信息日志"
msgid "Specify the following URL during the Runner setup:"
msgstr "在 Runner 设置时指定以下 URL:"
@@ -1370,7 +1388,7 @@ msgid "We don't have enough data to show this stage."
msgstr "该阶段的数据不足,无法显示。"
msgid "Wiki"
-msgstr ""
+msgstr "Wiki"
msgid "Withdraw Access Request"
msgstr "取消权限申请"
diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po
index fee0d661c7a..48b86508d1e 100644
--- a/locale/zh_HK/gitlab.po
+++ b/locale/zh_HK/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:21-0400\n"
+"PO-Revision-Date: 2017-09-15 05:21-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Chinese Traditional, Hong Kong\n"
"Language: zh_HK\n"
@@ -975,6 +975,24 @@ msgstr "分支圖"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr "推送事件 (push event) "
diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po
index 09c07a83d34..da6a98bdb5c 100644
--- a/locale/zh_TW/gitlab.po
+++ b/locale/zh_TW/gitlab.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: gitlab-ee\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-06 08:32+0200\n"
-"PO-Revision-Date: 2017-09-06 06:20-0400\n"
+"PO-Revision-Date: 2017-09-15 05:21-0400\n"
"Last-Translator: gitlab <mbartlett+crowdin@gitlab.com>\n"
"Language-Team: Chinese Traditional\n"
"Language: zh_TW\n"
@@ -34,7 +34,7 @@ msgid "%{number_of_failures} of %{maximum_failures} failures. GitLab will block
msgstr "已失敗 %{number_of_failures} 次,在失敗 %{maximum_failures} 次前 GitLab 會在 %{number_of_seconds} 秒後重試。"
msgid "%{number_of_failures} of %{maximum_failures} failures. GitLab will not retry automatically. Reset storage information when the problem is resolved."
-msgstr ""
+msgstr "已失敗 %{number_of_failures} / %{maximum_failures} 次,GitLab 將不再自動重試。請在確認問題解決後手動重置儲存空間資訊。"
msgid "%{storage_name}: failed storage access attempt on host:"
msgid_plural "%{storage_name}: %{failed_attempts} failed storage access attempts:"
@@ -90,10 +90,10 @@ msgid "All"
msgstr "全部"
msgid "Appearances"
-msgstr ""
+msgstr "外觀"
msgid "Applications"
-msgstr ""
+msgstr "應用程式"
msgid "Archived project! Repository is read-only"
msgstr "此專案已封存!檔案庫 (repository) 為唯讀狀態"
@@ -480,7 +480,7 @@ msgid "Edit Pipeline Schedule %{id}"
msgstr "編輯 %{id} 流水線 (pipeline) 排程"
msgid "Emails"
-msgstr ""
+msgstr "電子郵件"
msgid "EventFilterBy|Filter by all"
msgstr "顯示全部"
@@ -565,7 +565,7 @@ msgid "GoToYourFork|Fork"
msgstr "前往您的分支 (fork) "
msgid "Group overview"
-msgstr ""
+msgstr "群組總覽"
msgid "Health Check"
msgstr "健康檢查"
@@ -610,7 +610,7 @@ msgid "Issue events"
msgstr "議題 (issue) 事件"
msgid "Issues"
-msgstr ""
+msgstr "議題"
msgid "LFSStatus|Disabled"
msgstr "停用"
@@ -619,7 +619,7 @@ msgid "LFSStatus|Enabled"
msgstr "啟用"
msgid "Labels"
-msgstr ""
+msgstr "標籤"
msgid "Last %d day"
msgid_plural "Last %d days"
@@ -666,7 +666,7 @@ msgid "Median"
msgstr "中位數"
msgid "Members"
-msgstr ""
+msgstr "成員"
msgid "Merge Requests"
msgstr ""
@@ -675,13 +675,13 @@ msgid "Merge events"
msgstr "合併 (merge) 事件"
msgid "Messages"
-msgstr ""
+msgstr "訊息"
msgid "MissingSSHKeyWarningLink|add an SSH key"
msgstr "新增 SSH 金鑰"
msgid "Monitoring"
-msgstr ""
+msgstr "監控"
msgid "More information is available|here"
msgstr "健康檢查"
@@ -784,7 +784,7 @@ msgid "NotificationLevel|Watch"
msgstr "關注"
msgid "Notifications"
-msgstr ""
+msgstr "通知"
msgid "OfSearchInADropdown|Filter"
msgstr "篩選"
@@ -796,13 +796,13 @@ msgid "Options"
msgstr "選項"
msgid "Overview"
-msgstr ""
+msgstr "總覽"
msgid "Owner"
msgstr "所有權"
msgid "Password"
-msgstr ""
+msgstr "密碼"
msgid "Pipeline"
msgstr "流水線 (pipeline) "
@@ -946,7 +946,7 @@ msgid "Project home"
msgstr "專案首頁"
msgid "Project overview"
-msgstr ""
+msgstr "專案總覽"
msgid "ProjectActivityRSS|Subscribe"
msgstr "訂閱"
@@ -975,6 +975,24 @@ msgstr "分支圖"
msgid "Push Rules"
msgstr ""
+msgid "ProjectsDropdown|Loading projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Sorry, no projects matched your search"
+msgstr ""
+
+msgid "ProjectsDropdown|Projects you visit often will appear here"
+msgstr ""
+
+msgid "ProjectsDropdown|Search your projects"
+msgstr ""
+
+msgid "ProjectsDropdown|Something went wrong on our end"
+msgstr ""
+
+msgid "ProjectsDropdown|This feature requires browser localStorage support"
+msgstr ""
+
msgid "Push events"
msgstr "推送 (push) 事件"
@@ -1063,7 +1081,7 @@ msgid "Select target branch"
msgstr "選擇目標分支 (branch) "
msgid "Service Templates"
-msgstr ""
+msgstr "服務範本"
msgid "Set a password on your account to pull or push via %{protocol}."
msgstr "請先設定密碼,才能使用 %{protocol} 來上傳 (push) 或下載 (pull) 。"
@@ -1081,7 +1099,7 @@ msgid "SetPasswordToCloneLink|set a password"
msgstr "設定密碼"
msgid "Settings"
-msgstr ""
+msgstr "設定"
msgid "Showing %d event"
msgid_plural "Showing %d events"
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index 74e53d86266..178c5ea6930 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -11,7 +11,7 @@ module QA
end
def go_to_admin_area
- within_top_menu { click_link 'Admin area' }
+ within_top_menu { find('.admin-icon').click }
end
def sign_out
diff --git a/spec/controllers/projects/pipelines_settings_controller_spec.rb b/spec/controllers/projects/pipelines_settings_controller_spec.rb
new file mode 100644
index 00000000000..ee46ad00947
--- /dev/null
+++ b/spec/controllers/projects/pipelines_settings_controller_spec.rb
@@ -0,0 +1,43 @@
+require 'spec_helper'
+
+describe Projects::PipelinesSettingsController do
+ set(:user) { create(:user) }
+ set(:project_auto_devops) { create(:project_auto_devops) }
+ let(:project) { project_auto_devops.project }
+
+ before do
+ project.add_master(user)
+
+ sign_in(user)
+ end
+
+ describe 'PATCH update' do
+ before do
+ patch :update,
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ project: {
+ auto_devops_attributes: params
+ }
+ end
+
+ context 'when updating the auto_devops settings' do
+ let(:params) { { enabled: '', domain: 'mepmep.md' } }
+
+ it 'redirects to the settings page' do
+ expect(response).to have_http_status(302)
+ expect(flash[:notice]).to eq("Pipelines settings for '#{project.name}' were successfully updated.")
+ end
+
+ context 'following the instance default' do
+ let(:params) { { enabled: '' } }
+
+ it 'allows enabled to be set to nil' do
+ project_auto_devops.reload
+
+ expect(project_auto_devops.enabled).to be_nil
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb
index fd991293ee9..443b596b3c6 100644
--- a/spec/features/merge_requests/widget_spec.rb
+++ b/spec/features/merge_requests/widget_spec.rb
@@ -142,6 +142,24 @@ describe 'Merge request', :js do
end
end
+ context 'view merge request where project has CI setup but no CI status' do
+ before do
+ pipeline = create(:ci_pipeline, project: project,
+ sha: merge_request.diff_head_sha,
+ ref: merge_request.source_branch)
+ create(:ci_build, pipeline: pipeline)
+
+ visit project_merge_request_path(project, merge_request)
+ end
+
+ it 'has pipeline error text' do
+ # Wait for the `ci_status` and `merge_check` requests
+ wait_for_requests
+
+ expect(page).to have_text('Could not connect to the CI server. Please check your settings and try again')
+ end
+ end
+
context 'view merge request with MWPS enabled but automatically merge fails' do
before do
merge_request.update(
diff --git a/spec/fixtures/api/schemas/public_api/v4/user/admins.json b/spec/fixtures/api/schemas/public_api/v4/user/admins.json
new file mode 100644
index 00000000000..4a107f0ddbe
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/user/admins.json
@@ -0,0 +1,4 @@
+{
+ "type": "array",
+ "items": { "$ref": "admin.json" }
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/user/basics.json b/spec/fixtures/api/schemas/public_api/v4/user/basics.json
new file mode 100644
index 00000000000..6f7cf42229d
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/user/basics.json
@@ -0,0 +1,4 @@
+{
+ "type": "array",
+ "items": { "$ref": "basic.json" }
+}
diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb
index c4f4e0d21dc..5a2e4b34069 100644
--- a/spec/helpers/submodule_helper_spec.rb
+++ b/spec/helpers/submodule_helper_spec.rb
@@ -147,6 +147,12 @@ describe SubmoduleHelper do
expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
end
+ it 'sanitizes invalid URL with extended ASCII' do
+ stub_url('é')
+
+ expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
+ end
+
it 'returns original' do
stub_url('http://mygitserver.com/gitlab-org/gitlab-ce')
expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
index c763487d12f..690665ae12c 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
@@ -37,6 +37,26 @@ describe('MRWidgetPipeline', () => {
});
});
+ describe('hasPipeline', () => {
+ it('should return true when there is a pipeline', () => {
+ expect(Object.keys(mockData.pipeline).length).toBeGreaterThan(0);
+
+ const vm = createComponent({
+ pipeline: mockData.pipeline,
+ });
+
+ expect(vm.hasPipeline).toBeTruthy();
+ });
+
+ it('should return false when there is no pipeline', () => {
+ const vm = createComponent({
+ pipeline: null,
+ });
+
+ expect(vm.hasPipeline).toBeFalsy();
+ });
+ });
+
describe('hasCIError', () => {
it('should return false when there is no CI error', () => {
const vm = createComponent({
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index c607c9746a4..03a52f1f91c 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -11,6 +11,7 @@ const createComponent = (customConfig = {}) => {
isPipelineActive: false,
pipeline: null,
isPipelineFailed: false,
+ isPipelinePassing: false,
onlyAllowMergeIfPipelineSucceeds: false,
hasCI: false,
ciStatus: null,
@@ -68,6 +69,18 @@ describe('MRWidgetReadyToMerge', () => {
});
describe('computed', () => {
+ describe('shouldShowMergeWhenPipelineSucceedsText', () => {
+ it('should return true with active pipeline', () => {
+ vm.mr.isPipelineActive = true;
+ expect(vm.shouldShowMergeWhenPipelineSucceedsText).toBeTruthy();
+ });
+
+ it('should return false with inactive pipeline', () => {
+ vm.mr.isPipelineActive = false;
+ expect(vm.shouldShowMergeWhenPipelineSucceedsText).toBeFalsy();
+ });
+ });
+
describe('commitMessageLinkTitle', () => {
const withDesc = 'Include description in commit message';
const withoutDesc = "Don't include description in commit message";
@@ -83,7 +96,7 @@ describe('MRWidgetReadyToMerge', () => {
});
describe('mergeButtonClass', () => {
- const defaultClass = 'btn btn-small btn-success accept-merge-request';
+ const defaultClass = 'btn btn-sm btn-success accept-merge-request';
const failedClass = `${defaultClass} btn-danger`;
const inActionClass = `${defaultClass} btn-info`;
@@ -203,20 +216,55 @@ describe('MRWidgetReadyToMerge', () => {
describe('methods', () => {
describe('isMergeAllowed', () => {
- it('should return false with initial data', () => {
+ it('should return true when no pipeline and not required to succeed', () => {
+ vm.mr.onlyAllowMergeIfPipelineSucceeds = false;
+ vm.mr.isPipelinePassing = false;
expect(vm.isMergeAllowed()).toBeTruthy();
});
- it('should return false when MR is set only merge when pipeline succeeds', () => {
- vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
+ it('should return true when pipeline failed and not required to succeed', () => {
+ vm.mr.onlyAllowMergeIfPipelineSucceeds = false;
+ vm.mr.isPipelinePassing = false;
expect(vm.isMergeAllowed()).toBeTruthy();
});
- it('should return true true', () => {
+ it('should return false when pipeline failed and required to succeed', () => {
vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
- vm.mr.isPipelineFailed = true;
+ vm.mr.isPipelinePassing = false;
expect(vm.isMergeAllowed()).toBeFalsy();
});
+
+ it('should return true when pipeline succeeded and required to succeed', () => {
+ vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
+ vm.mr.isPipelinePassing = true;
+ expect(vm.isMergeAllowed()).toBeTruthy();
+ });
+ });
+
+ describe('shouldShowMergeControls', () => {
+ it('should return false when an external pipeline is running and required to succeed', () => {
+ spyOn(vm, 'isMergeAllowed').and.returnValue(false);
+ vm.mr.isPipelineActive = false;
+ expect(vm.shouldShowMergeControls()).toBeFalsy();
+ });
+
+ it('should return true when the build succeeded or build not required to succeed', () => {
+ spyOn(vm, 'isMergeAllowed').and.returnValue(true);
+ vm.mr.isPipelineActive = false;
+ expect(vm.shouldShowMergeControls()).toBeTruthy();
+ });
+
+ it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => {
+ spyOn(vm, 'isMergeAllowed').and.returnValue(false);
+ vm.mr.isPipelineActive = true;
+ expect(vm.shouldShowMergeControls()).toBeTruthy();
+ });
+
+ it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => {
+ spyOn(vm, 'isMergeAllowed').and.returnValue(true);
+ vm.mr.isPipelineActive = true;
+ expect(vm.shouldShowMergeControls()).toBeTruthy();
+ });
});
describe('updateCommitMessage', () => {
diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
index 669ee248bf1..da66c7504cb 100644
--- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
@@ -59,23 +59,15 @@ describe('mrWidgetOptions', () => {
});
describe('shouldRenderPipelines', () => {
- it('should return true for the initial data', () => {
- expect(vm.shouldRenderPipelines).toBeTruthy();
- });
+ it('should return true when hasCI is true', () => {
+ vm.mr.hasCI = true;
- it('should return true when pipeline is empty but MR.hasCI is set to true', () => {
- vm.mr.pipeline = {};
expect(vm.shouldRenderPipelines).toBeTruthy();
});
- it('should return true when pipeline available', () => {
+ it('should return false when hasCI is false', () => {
vm.mr.hasCI = false;
- expect(vm.shouldRenderPipelines).toBeTruthy();
- });
- it('should return false when there is no pipeline', () => {
- vm.mr.pipeline = {};
- vm.mr.hasCI = false;
expect(vm.shouldRenderPipelines).toBeFalsy();
});
});
diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
index 56dd0198ae2..8e5614b20f0 100644
--- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
+++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
@@ -18,5 +18,39 @@ describe('MergeRequestStore', () => {
store.setData({ ...mockData, work_in_progress: !mockData.work_in_progress });
expect(store.hasSHAChanged).toBe(false);
});
+
+ describe('isPipelinePassing', () => {
+ it('is true when the CI status is `success`', () => {
+ store.setData({ ...mockData, ci_status: 'success' });
+ expect(store.isPipelinePassing).toBe(true);
+ });
+
+ it('is true when the CI status is `success_with_warnings`', () => {
+ store.setData({ ...mockData, ci_status: 'success_with_warnings' });
+ expect(store.isPipelinePassing).toBe(true);
+ });
+
+ it('is false when the CI status is `failed`', () => {
+ store.setData({ ...mockData, ci_status: 'failed' });
+ expect(store.isPipelinePassing).toBe(false);
+ });
+
+ it('is false when the CI status is anything except `success`', () => {
+ store.setData({ ...mockData, ci_status: 'foobarbaz' });
+ expect(store.isPipelinePassing).toBe(false);
+ });
+ });
+
+ describe('isPipelineSkipped', () => {
+ it('should set isPipelineSkipped=true when the CI status is `skipped`', () => {
+ store.setData({ ...mockData, ci_status: 'skipped' });
+ expect(store.isPipelineSkipped).toBe(true);
+ });
+
+ it('should set isPipelineSkipped=false when the CI status is anything except `skipped`', () => {
+ store.setData({ ...mockData, ci_status: 'foobarbaz' });
+ expect(store.isPipelineSkipped).toBe(false);
+ });
+ });
});
});
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index b186a78e44a..17dc3bb4f48 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -11,10 +11,11 @@ describe GroupPolicy do
let(:reporter_permissions) { [:admin_label] }
+ let(:developer_permissions) { [:admin_milestones] }
+
let(:master_permissions) do
[
- :create_projects,
- :admin_milestones
+ :create_projects
]
end
@@ -52,6 +53,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_disallowed(*reporter_permissions)
+ expect_disallowed(*developer_permissions)
expect_disallowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -63,6 +65,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_disallowed(*reporter_permissions)
+ expect_disallowed(*developer_permissions)
expect_disallowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -74,6 +77,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_disallowed(*developer_permissions)
expect_disallowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -85,6 +89,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_allowed(*developer_permissions)
expect_disallowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -96,6 +101,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_allowed(*developer_permissions)
expect_allowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -109,6 +115,7 @@ describe GroupPolicy do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_allowed(*developer_permissions)
expect_allowed(*master_permissions)
expect_allowed(*owner_permissions)
end
@@ -122,6 +129,7 @@ describe GroupPolicy do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_allowed(*developer_permissions)
expect_allowed(*master_permissions)
expect_allowed(*owner_permissions)
end
@@ -180,6 +188,7 @@ describe GroupPolicy do
it do
expect_disallowed(:read_group)
expect_disallowed(*reporter_permissions)
+ expect_disallowed(*developer_permissions)
expect_disallowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -191,6 +200,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_disallowed(*reporter_permissions)
+ expect_disallowed(*developer_permissions)
expect_disallowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -202,6 +212,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_disallowed(*developer_permissions)
expect_disallowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -213,6 +224,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_allowed(*developer_permissions)
expect_disallowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -224,6 +236,7 @@ describe GroupPolicy do
it do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_allowed(*developer_permissions)
expect_allowed(*master_permissions)
expect_disallowed(*owner_permissions)
end
@@ -237,6 +250,7 @@ describe GroupPolicy do
expect_allowed(:read_group)
expect_allowed(*reporter_permissions)
+ expect_allowed(*developer_permissions)
expect_allowed(*master_permissions)
expect_allowed(*owner_permissions)
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 4dbaf7fb025..c0cbdeed03d 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -33,7 +33,7 @@ describe ProjectPolicy do
let(:developer_permissions) do
%i[
- admin_merge_request update_merge_request create_commit_status
+ admin_milestone admin_merge_request update_merge_request create_commit_status
update_commit_status create_build update_build create_pipeline
update_pipeline create_merge_request create_wiki push_code
resolve_note create_container_image update_container_image
@@ -44,7 +44,7 @@ describe ProjectPolicy do
let(:master_permissions) do
%i[
delete_protected_branch update_project_snippet update_environment
- update_deployment admin_milestone admin_project_snippet
+ update_deployment admin_project_snippet
admin_project_member admin_note admin_wiki admin_project
admin_commit_status admin_build admin_container_image
admin_pipeline admin_environment admin_deployment
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 37cb95a16e3..5b306ec6cbf 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -23,8 +23,7 @@ describe API::Users do
it "returns the user when a valid `username` parameter is passed" do
get api("/users"), username: user.username
- expect(response).to have_gitlab_http_status(200)
- expect(json_response).to be_an Array
+ expect(response).to match_response_schema('public_api/v4/user/basics')
expect(json_response.size).to eq(1)
expect(json_response[0]['id']).to eq(user.id)
expect(json_response[0]['username']).to eq(user.username)
@@ -68,7 +67,7 @@ describe API::Users do
it "renders 200" do
get api("/users", user)
- expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/basics')
end
end
@@ -76,7 +75,7 @@ describe API::Users do
it "renders 200" do
get api("/users", admin)
- expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/basics')
end
end
end
@@ -84,9 +83,8 @@ describe API::Users do
it "returns an array of users" do
get api("/users", user)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/basics')
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
username = user.username
expect(json_response.detect do |user|
user['username'] == username
@@ -99,18 +97,16 @@ describe API::Users do
get api("/users?blocked=true", user)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/basics')
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
expect(json_response).to all(include('state' => /(blocked|ldap_blocked)/))
end
it "returns one user" do
get api("/users?username=#{omniauth_user.username}", user)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/basics')
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
expect(json_response.first['username']).to eq(omniauth_user.username)
end
@@ -123,6 +119,7 @@ describe API::Users do
it 'does not reveal the `is_admin` flag of the user' do
get api('/users', user)
+ expect(response).to match_response_schema('public_api/v4/user/basics')
expect(json_response.first.keys).not_to include 'is_admin'
end
end
@@ -131,17 +128,8 @@ describe API::Users do
it "returns an array of users" do
get api("/users", admin)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/admins')
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response.first.keys).to include 'email'
- expect(json_response.first.keys).to include 'organization'
- expect(json_response.first.keys).to include 'identities'
- expect(json_response.first.keys).to include 'can_create_project'
- expect(json_response.first.keys).to include 'two_factor_enabled'
- expect(json_response.first.keys).to include 'last_sign_in_at'
- expect(json_response.first.keys).to include 'confirmed_at'
- expect(json_response.first.keys).to include 'is_admin'
end
it "returns an array of external users" do
@@ -149,17 +137,15 @@ describe API::Users do
get api("/users?external=true", admin)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/admins')
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
expect(json_response).to all(include('external' => true))
end
it "returns one user by external UID" do
get api("/users?extern_uid=#{omniauth_user.identities.first.extern_uid}&provider=#{omniauth_user.identities.first.provider}", admin)
- expect(response).to have_http_status(200)
- expect(json_response).to be_an Array
+ expect(response).to match_response_schema('public_api/v4/user/admins')
expect(json_response.size).to eq(1)
expect(json_response.first['username']).to eq(omniauth_user.username)
end
@@ -181,7 +167,7 @@ describe API::Users do
get api("/users?created_before=2000-01-02T00:00:00.060Z", admin)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/admins')
expect(json_response.size).to eq(1)
expect(json_response.first['username']).to eq(user.username)
end
@@ -191,7 +177,7 @@ describe API::Users do
get api("/users?created_before=2000-01-02T00:00:00.060Z", admin)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/admins')
expect(json_response.size).to eq(0)
end
@@ -200,7 +186,7 @@ describe API::Users do
get api("/users?created_before=2001-01-02T00:00:00.060Z&created_after=1999-01-02T00:00:00.060", admin)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/admins')
expect(json_response.size).to eq(1)
expect(json_response.first['username']).to eq(user.username)
end
@@ -211,22 +197,22 @@ describe API::Users do
it "returns a user by id" do
get api("/users/#{user.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/basic')
expect(json_response['username']).to eq(user.username)
end
it "does not return the user's `is_admin` flag" do
get api("/users/#{user.id}", user)
- expect(response).to have_http_status(200)
- expect(json_response['is_admin']).to be_nil
+ expect(response).to match_response_schema('public_api/v4/user/basic')
+ expect(json_response.keys).not_to include 'is_admin'
end
context 'when authenticated as admin' do
it 'includes the `is_admin` field' do
get api("/users/#{user.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/admin')
expect(json_response['is_admin']).to be(false)
end
end
@@ -235,7 +221,7 @@ describe API::Users do
it "returns a user by id" do
get api("/users/#{user.id}")
- expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/basic')
expect(json_response['username']).to eq(user.username)
end
@@ -251,6 +237,7 @@ describe API::Users do
it "returns a 404 error if user id not found" do
get api("/users/9999", user)
+
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end