提交 13867d66 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 83758a4e
...@@ -411,6 +411,7 @@ linters: ...@@ -411,6 +411,7 @@ linters:
- 'app/views/shared/snippets/_snippet.html.haml' - 'app/views/shared/snippets/_snippet.html.haml'
- 'app/views/shared/tokens/_scopes_list.html.haml' - 'app/views/shared/tokens/_scopes_list.html.haml'
- 'app/views/shared/web_hooks/_form.html.haml' - 'app/views/shared/web_hooks/_form.html.haml'
- 'app/views/shared/web_hooks/_hook.html.haml'
- 'app/views/shared/web_hooks/_test_button.html.haml' - 'app/views/shared/web_hooks/_test_button.html.haml'
- 'app/views/u2f/_authenticate.html.haml' - 'app/views/u2f/_authenticate.html.haml'
- 'app/views/u2f/_register.html.haml' - 'app/views/u2f/_register.html.haml'
...@@ -442,7 +443,7 @@ linters: ...@@ -442,7 +443,7 @@ linters:
- 'ee/app/views/groups/epics/_epic.html.haml' - 'ee/app/views/groups/epics/_epic.html.haml'
- 'ee/app/views/groups/group_members/_ldap_sync.html.haml' - 'ee/app/views/groups/group_members/_ldap_sync.html.haml'
- 'ee/app/views/groups/group_members/_sync_button.html.haml' - 'ee/app/views/groups/group_members/_sync_button.html.haml'
- 'ee/app/views/groups/hooks/_project_hook.html.haml' - 'ee/app/views/groups/hooks/edit.html.haml'
- 'ee/app/views/groups/hooks/index.html.haml' - 'ee/app/views/groups/hooks/index.html.haml'
- 'ee/app/views/groups/ldap_group_links/index.html.haml' - 'ee/app/views/groups/ldap_group_links/index.html.haml'
- 'ee/app/views/groups/pipeline_quota/index.html.haml' - 'ee/app/views/groups/pipeline_quota/index.html.haml'
......
...@@ -54,7 +54,7 @@ gem 'gssapi', group: :kerberos ...@@ -54,7 +54,7 @@ gem 'gssapi', group: :kerberos
# Spam and anti-bot protection # Spam and anti-bot protection
gem 'recaptcha', '~> 4.11', require: 'recaptcha/rails' gem 'recaptcha', '~> 4.11', require: 'recaptcha/rails'
gem 'akismet', '~> 2.0' gem 'akismet', '~> 3.0'
gem 'invisible_captcha', '~> 0.12.1' gem 'invisible_captcha', '~> 0.12.1'
# Two-factor authentication # Two-factor authentication
......
...@@ -58,7 +58,7 @@ GEM ...@@ -58,7 +58,7 @@ GEM
addressable (2.5.2) addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0) public_suffix (>= 2.0.2, < 4.0)
aes_key_wrap (1.0.1) aes_key_wrap (1.0.1)
akismet (2.0.0) akismet (3.0.0)
apollo_upload_server (2.0.0.beta.3) apollo_upload_server (2.0.0.beta.3)
graphql (>= 1.8) graphql (>= 1.8)
rails (>= 4.2) rails (>= 4.2)
...@@ -1120,7 +1120,7 @@ DEPENDENCIES ...@@ -1120,7 +1120,7 @@ DEPENDENCIES
activerecord-explain-analyze (~> 0.1) activerecord-explain-analyze (~> 0.1)
acts-as-taggable-on (~> 6.0) acts-as-taggable-on (~> 6.0)
addressable (~> 2.5.2) addressable (~> 2.5.2)
akismet (~> 2.0) akismet (~> 3.0)
apollo_upload_server (~> 2.0.0.beta3) apollo_upload_server (~> 2.0.0.beta3)
asana (~> 0.9) asana (~> 0.9)
asciidoctor (~> 2.0.10) asciidoctor (~> 2.0.10)
......
...@@ -35,11 +35,13 @@ export default { ...@@ -35,11 +35,13 @@ export default {
<template> <template>
<article class="file-holder limited-width-container readme-holder"> <article class="file-holder limited-width-container readme-holder">
<div class="file-title"> <div class="js-file-title file-title-flex-parent">
<i aria-hidden="true" class="fa fa-file-text-o fa-fw"></i> <div class="file-header-content">
<gl-link :href="blob.webUrl"> <i aria-hidden="true" class="fa fa-file-text-o fa-fw"></i>
<strong>{{ blob.name }}</strong> <gl-link :href="blob.webUrl">
</gl-link> <strong>{{ blob.name }}</strong>
</gl-link>
</div>
</div> </div>
<div class="blob-viewer"> <div class="blob-viewer">
<gl-loading-icon v-if="loading > 0" size="md" class="my-4 mx-auto" /> <gl-loading-icon v-if="loading > 0" size="md" class="my-4 mx-auto" />
......
...@@ -645,6 +645,12 @@ h4 { ...@@ -645,6 +645,12 @@ h4 {
} }
} }
.text-right-md {
@include media-breakpoint-up(md) {
text-align: right;
}
}
.text-right-lg { .text-right-lg {
@include media-breakpoint-up(lg) { @include media-breakpoint-up(lg) {
text-align: right; text-align: right;
......
...@@ -2,18 +2,40 @@ ...@@ -2,18 +2,40 @@
module HooksHelper module HooksHelper
def link_to_test_hook(hook, trigger) def link_to_test_hook(hook, trigger)
path = case hook path = test_hook_path(hook, trigger)
when ProjectHook
project = hook.project
test_project_hook_path(project, hook, trigger: trigger)
when SystemHook
test_admin_hook_path(hook, trigger: trigger)
end
trigger_human_name = trigger.to_s.tr('_', ' ').camelize trigger_human_name = trigger.to_s.tr('_', ' ').camelize
link_to path, rel: 'nofollow', method: :post do link_to path, rel: 'nofollow', method: :post do
content_tag(:span, trigger_human_name) content_tag(:span, trigger_human_name)
end end
end end
def test_hook_path(hook, trigger)
case hook
when ProjectHook
test_project_hook_path(hook.project, hook, trigger: trigger)
when SystemHook
test_admin_hook_path(hook, trigger: trigger)
end
end
def edit_hook_path(hook)
case hook
when ProjectHook
edit_project_hook_path(hook.project, hook)
when SystemHook
edit_admin_hook_path(hook)
end
end
def destroy_hook_path(hook)
case hook
when ProjectHook
project_hook_path(hook.project, hook)
when SystemHook
admin_hook_path(hook)
end
end
end end
HooksHelper.prepend_if_ee('EE::HooksHelper')
...@@ -18,6 +18,10 @@ class ProjectHook < WebHook ...@@ -18,6 +18,10 @@ class ProjectHook < WebHook
belongs_to :project belongs_to :project
validates :project, presence: true validates :project, presence: true
def pluralized_name
_('Project Hooks')
end
end end
ProjectHook.prepend_if_ee('EE::ProjectHook') ProjectHook.prepend_if_ee('EE::ProjectHook')
...@@ -20,4 +20,12 @@ class SystemHook < WebHook ...@@ -20,4 +20,12 @@ class SystemHook < WebHook
def allow_local_requests? def allow_local_requests?
Gitlab::CurrentSettings.allow_local_requests_from_system_hooks? Gitlab::CurrentSettings.allow_local_requests_from_system_hooks?
end end
def pluralized_name
_('System Hooks')
end
def help_path
'system_hooks/system_hooks'
end
end end
...@@ -37,4 +37,8 @@ class WebHook < ApplicationRecord ...@@ -37,4 +37,8 @@ class WebHook < ApplicationRecord
def allow_local_requests? def allow_local_requests?
Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services? Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
end end
def help_path
'user/project/integrations/webhooks'
end
end end
- add_to_breadcrumbs "System Hooks", admin_hooks_path - add_to_breadcrumbs @hook.pluralized_name, admin_hooks_path
- page_title 'Edit System Hook' - page_title _('Edit System Hook')
%h3.page-title
Edit System Hook
%p.light .row.prepend-top-default
#{link_to 'System hooks ', help_page_path('system_hooks/system_hooks')} can be .col-lg-3
used for binding events when GitLab creates a User or Project. = render 'shared/web_hooks/title_and_docs', hook: @hook
%hr .col-lg-9.append-bottom-default
= form_for @hook, as: :hook, url: admin_hook_path do |f|
= render partial: 'form', locals: { form: f, hook: @hook }
.form-actions
%span>= f.submit _('Save changes'), class: 'btn btn-success append-right-8'
= render 'shared/web_hooks/test_button', hook: @hook
= link_to _('Delete'), admin_hook_path(@hook), method: :delete, class: 'btn btn-remove float-right', data: { confirm: _('Are you sure?') }
= form_for @hook, as: :hook, url: admin_hook_path do |f| %hr
= render partial: 'form', locals: { form: f, hook: @hook }
.form-actions
= f.submit 'Save changes', class: 'btn btn-success'
= render 'shared/web_hooks/test_button', triggers: SystemHook.triggers, hook: @hook
= link_to 'Remove', admin_hook_path(@hook), method: :delete, class: 'btn btn-remove float-right', data: { confirm: 'Are you sure?' }
%hr = render partial: 'admin/hook_logs/index', locals: { hook: @hook, hook_logs: @hook_logs }
= render partial: 'admin/hook_logs/index', locals: { hook: @hook, hook_logs: @hook_logs }
- page_title 'System Hooks' - page_title @hook.pluralized_name
.row.prepend-top-default .row.prepend-top-default
.col-lg-4 .col-lg-4
%h4.prepend-top-0 = render 'shared/web_hooks/title_and_docs', hook: @hook
= page_title
%p
#{link_to 'System hooks ', help_page_path('system_hooks/system_hooks')} can be
used for binding events when GitLab creates a User or Project.
.col-lg-8.append-bottom-default .col-lg-8.append-bottom-default
= form_for @hook, as: :hook, url: admin_hooks_path do |f| = form_for @hook, as: :hook, url: admin_hooks_path do |f|
= render partial: 'form', locals: { form: f, hook: @hook } = render partial: 'form', locals: { form: f, hook: @hook }
= f.submit 'Add system hook', class: 'btn btn-success' = f.submit _('Add system hook'), class: 'btn btn-success'
%hr
- if @hooks.any? = render 'shared/web_hooks/index', hooks: @hooks, hook_class: @hook.class
.card
.card-header
System hooks (#{@hooks.count})
%ul.content-list
- @hooks.each do |hook|
%li
.controls
= 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
%div
- SystemHook.triggers.each_value do |event|
- if hook.public_send(event)
%span.badge.badge-gray= event.to_s.titleize
%span.badge.badge-gray SSL Verification: #{hook.enable_ssl_verification ? 'enabled' : 'disabled'}
= render 'shared/plugins/index' = render 'shared/plugins/index'
.row.prepend-top-default .row.prepend-top-default
.col-lg-4 .col-lg-4
%h4.prepend-top-0 = render 'shared/web_hooks/title_and_docs', hook: @hook
= page_title
%p
#{link_to 'Webhooks', help_page_path('user/project/integrations/webhooks')} can be
used for binding events when something is happening within the project.
.col-lg-8.append-bottom-default .col-lg-8.append-bottom-default
= form_for @hook, as: :hook, url: polymorphic_path([@project.namespace.becomes(Namespace), @project, :hooks]) do |f| = form_for @hook, as: :hook, url: polymorphic_path([@project.namespace.becomes(Namespace), @project, :hooks]) do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook } = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
= f.submit 'Add webhook', class: 'btn btn-success' = f.submit 'Add webhook', class: 'btn btn-success'
%hr = render 'shared/web_hooks/index', hooks: @hooks, hook_class: @hook.class
%h5.prepend-top-default
Webhooks (#{@hooks.count})
- if @hooks.any?
%ul.content-list
- @hooks.each do |hook|
= render 'project_hook', hook: hook
- else
%p.settings-message.text-center.append-bottom-0
No webhooks found, add one in the form above.
- page_title 'Integrations' - add_to_breadcrumbs _('ProjectService|Integrations'), namespace_project_settings_integrations_path
- page_title _('Edit Project Hook')
.row.prepend-top-default .row.prepend-top-default
.col-lg-3 .col-lg-3
%h4.prepend-top-0 = render 'shared/web_hooks/title_and_docs', hook: @hook
= page_title
%p
#{link_to 'Webhooks', help_page_path('user/project/integrations/webhooks')} can be
used for binding events when something is happening within the project.
.col-lg-9.append-bottom-default .col-lg-9.append-bottom-default
= form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: project_hook_path(@project, @hook) do |f| = form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: project_hook_path(@project, @hook) do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook } = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
= f.submit 'Save changes', class: 'btn btn-success' %span>= f.submit 'Save changes', class: 'btn btn-success append-right-8'
= render 'shared/web_hooks/test_button', triggers: ProjectHook.triggers, hook: @hook = render 'shared/web_hooks/test_button', hook: @hook
= link_to 'Remove', project_hook_path(@project, @hook), method: :delete, class: 'btn btn-remove float-right', data: { confirm: 'Are you sure?' } = link_to _('Delete'), project_hook_path(@project, @hook), method: :delete, class: 'btn btn-remove float-right', data: { confirm: _('Are you sure?') }
%hr %hr
......
%li
.row
.col-md-8.col-lg-7
%strong.light-header= hook.url
%div
- ProjectHook.triggers.each_value do |event|
- if hook.public_send(event)
%span.badge.badge-gray.deploy-project-label= event.to_s.titleize
.col-md-4.col-lg-5.text-right-lg.prepend-top-5
%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-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')
%li
.row
.col-md-8.col-lg-7
%strong.light-header= hook.url
%div
- hook.class.triggers.each_value do |trigger|
- if hook.public_send(trigger)
%span.badge.badge-gray.deploy-project-label= trigger.to_s.titleize
%span.badge.badge-gray
= _('SSL Verification:')
= hook.enable_ssl_verification ? _('enabled') : _('disabled')
.col-md-4.col-lg-5.text-right-md.prepend-top-5
%span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm append-right-8'
%span>= link_to _('Edit'), edit_hook_path(hook), class: 'btn btn-sm append-right-8'
= link_to _('Delete'), destroy_hook_path(hook), data: { confirm: _('Are you sure?') }, method: :delete, class: 'btn btn-sm'
%hr
.card
.card-header
%h5
= hook_class.underscore.humanize.titleize.pluralize
(#{hooks.count})
- if hooks.any?
%ul.content-list
- hooks.each do |hook|
= render 'shared/web_hooks/hook', hook: hook
- else
%p.text-center.prepend-top-default.append-bottom-default
= _('No webhooks found, add one in the form above.')
- triggers = local_assigns.fetch(:triggers)
- button_class = local_assigns.fetch(:button_class, '') - button_class = local_assigns.fetch(:button_class, '')
- hook = local_assigns.fetch(:hook) - hook = local_assigns.fetch(:hook)
- triggers = hook.class.triggers
.hook-test-button.dropdown.inline .hook-test-button.dropdown.inline>
%button.btn{ 'data-toggle' => 'dropdown', class: button_class } %button.btn{ 'data-toggle' => 'dropdown', class: button_class }
Test = _('Test')
= icon('caret-down') = icon('caret-down')
%ul.dropdown-menu.dropdown-menu-right{ role: 'menu' } %ul.dropdown-menu.dropdown-menu-right{ role: 'menu' }
- triggers.each_value do |event| - triggers.each_value do |event|
......
%h4.prepend-top-0
= page_title
%p
- link = link_to(hook.pluralized_name, help_page_path(hook.help_path))
= _('%{link} can be used for binding events when something is happening within the project.').html_safe % { link: link }
---
title: Add _links object to package api response
merge_request: 20820
author:
type: added
---
title: Fix top border of README in vue_file_list
merge_request: 21578
author: Hector Bustillos
type: fixed
---
title: Upgrade Akismet gem to v3.0.0
merge_request: 21786
author:
type: security
...@@ -79,6 +79,7 @@ postgresql['enable'] = false ...@@ -79,6 +79,7 @@ postgresql['enable'] = false
redis['enable'] = false redis['enable'] = false
nginx['enable'] = false nginx['enable'] = false
prometheus['enable'] = false prometheus['enable'] = false
grafana['enable'] = false
unicorn['enable'] = false unicorn['enable'] = false
sidekiq['enable'] = false sidekiq['enable'] = false
gitlab_workhorse['enable'] = false gitlab_workhorse['enable'] = false
...@@ -150,6 +151,7 @@ postgresql['enable'] = false ...@@ -150,6 +151,7 @@ postgresql['enable'] = false
redis['enable'] = false redis['enable'] = false
nginx['enable'] = false nginx['enable'] = false
prometheus['enable'] = false prometheus['enable'] = false
grafana['enable'] = false
unicorn['enable'] = false unicorn['enable'] = false
sidekiq['enable'] = false sidekiq['enable'] = false
gitlab_workhorse['enable'] = false gitlab_workhorse['enable'] = false
......
...@@ -107,7 +107,8 @@ working, you can remove the `repos_path` line. ...@@ -107,7 +107,8 @@ working, you can remove the `repos_path` line.
## Choose where new project repositories will be stored ## Choose where new project repositories will be stored
Once you set the multiple storage paths, you can choose where new projects will Once you set the multiple storage paths, you can choose where new projects will
be stored via the **Application Settings** in the Admin area. be stored under **Admin Area > Settings > Repository > Repository storage > Storage
nodes for new projects**.
![Choose repository storage path in Admin area](img/repository_storages_admin_ui.png) ![Choose repository storage path in Admin area](img/repository_storages_admin_ui.png)
......
...@@ -72,19 +72,32 @@ Example response: ...@@ -72,19 +72,32 @@ Example response:
"id": 1, "id": 1,
"name": "com/mycompany/my-app", "name": "com/mycompany/my-app",
"version": "1.0-SNAPSHOT", "version": "1.0-SNAPSHOT",
"package_type": "maven" "package_type": "maven",
"_links": {
"web_path": "/namespace1/project1/-/packages/1",
"delete_api_path": "/namespace1/project1/-/packages/1"
}
}, },
{ {
"id": 2, "id": 2,
"name": "@foo/bar", "name": "@foo/bar",
"version": "1.0.3", "version": "1.0.3",
"package_type": "npm" "package_type": "npm",
"_links": {
"web_path": "/namespace1/project1/-/packages/1",
"delete_api_path": "/namespace1/project1/-/packages/1"
}
} }
] ]
``` ```
By default, the `GET` request will return 20 results, since the API is [paginated](README.md#pagination). By default, the `GET` request will return 20 results, since the API is [paginated](README.md#pagination).
The `_links` object contains the following properties:
- `web_path`: The path which you can visit in GitLab and see the details of the package.
- `delete_api_path`: The API path to delete the package. Only available if the request user has permission to do so.
## Get a project package ## Get a project package
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/9667) in GitLab 11.9. > [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/9667) in GitLab 11.9.
...@@ -111,10 +124,19 @@ Example response: ...@@ -111,10 +124,19 @@ Example response:
"id": 1, "id": 1,
"name": "com/mycompany/my-app", "name": "com/mycompany/my-app",
"version": "1.0-SNAPSHOT", "version": "1.0-SNAPSHOT",
"package_type": "maven" "package_type": "maven",
"_links": {
"web_path": "/namespace1/project1/-/packages/1",
"delete_api_path": "/namespace1/project1/-/packages/1"
}
} }
``` ```
The `_links` object contains the following properties:
- `web_path`: The path which you can visit in GitLab and see the details of the package.
- `delete_api_path`: The API path to delete the package. Only available if the request user has permission to do so.
## List package files ## List package files
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/9305) in GitLab 11.8. > [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/9305) in GitLab 11.8.
......
...@@ -358,7 +358,7 @@ it highlighted: ...@@ -358,7 +358,7 @@ it highlighted:
} }
``` ```
Here is the description of the report file structure nodes and their meaning. All fields are mandatory to be present in Here is the description of the report file structure nodes and their meaning. All fields are mandatory in
the report JSON unless stated otherwise. Presence of optional fields depends on the underlying analyzers being used. the report JSON unless stated otherwise. Presence of optional fields depends on the underlying analyzers being used.
| Report JSON node | Function | | Report JSON node | Function |
......
...@@ -46,10 +46,11 @@ The following table depicts the various user permission levels in a project. ...@@ -46,10 +46,11 @@ The following table depicts the various user permission levels in a project.
| Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| Leave comments | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | Leave comments | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View Insights charts **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | | View Insights charts **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View approved/blacklisted licenses **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | | View approved/blacklisted licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | | View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
| View Dependency list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | View Dependency list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View License list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View licenses in Dependency list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | View licenses in Dependency list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View [Design Management](project/issues/design_management.md) pages **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | | View [Design Management](project/issues/design_management.md) pages **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
......
...@@ -53,7 +53,12 @@ From error list, users can navigate to the error details page by clicking the ti ...@@ -53,7 +53,12 @@ From error list, users can navigate to the error details page by clicking the ti
This page has: This page has:
- A link to the Sentry issue. - A link to the Sentry issue.
- A full stack trace along with other details. - Other details about the issue, including a full stack trace.
- Ability to create an issue from a Sentry error.
![Error Details](img/error_details_v12_6.png) If the error has not been linked to an existing GitLab issue, a 'Create Issue' button will be visible:
![Error Details without Issue Link](img/error_details_v12_6.png)
If a link does exist, it will be shown in the details and the 'Create Issue' button will be hidden:
![Error Details with Issue Link](img/error_details_with_issue_v12_6.png)
...@@ -55,7 +55,7 @@ you can skip the step 1 below; you only need to enable it per project. ...@@ -55,7 +55,7 @@ you can skip the step 1 below; you only need to enable it per project.
1. [Set up incoming email](../../administration/incoming_email.md#set-it-up) for the GitLab instance. This must 1. [Set up incoming email](../../administration/incoming_email.md#set-it-up) for the GitLab instance. This must
support [email sub-addressing](../../administration/incoming_email.md#email-sub-addressing). support [email sub-addressing](../../administration/incoming_email.md#email-sub-addressing).
1. Navigate to your project's **Settings** and scroll down to the **Service Desk** 1. Navigate to your project's **Settings > General** and scroll down to the **Service Desk**
section. section.
1. If you have the correct access and a Premium license, 1. If you have the correct access and a Premium license,
you will see an option to set up Service Desk: you will see an option to set up Service Desk:
......
...@@ -299,6 +299,9 @@ msgstr "" ...@@ -299,6 +299,9 @@ msgstr ""
msgid "%{link_start}Read more%{link_end} about role permissions" msgid "%{link_start}Read more%{link_end} about role permissions"
msgstr "" msgstr ""
msgid "%{link} can be used for binding events when something is happening within the project."
msgstr ""
msgid "%{listToShow}, and %{awardsListLength} more." msgid "%{listToShow}, and %{awardsListLength} more."
msgstr "" msgstr ""
...@@ -1055,6 +1058,9 @@ msgstr "" ...@@ -1055,6 +1058,9 @@ msgstr ""
msgid "Add request manually" msgid "Add request manually"
msgstr "" msgstr ""
msgid "Add system hook"
msgstr ""
msgid "Add to Slack" msgid "Add to Slack"
msgstr "" msgstr ""
...@@ -1082,6 +1088,9 @@ msgstr "" ...@@ -1082,6 +1088,9 @@ msgstr ""
msgid "Add users to group" msgid "Add users to group"
msgstr "" msgstr ""
msgid "Add webhook"
msgstr ""
msgid "AddMember|No users specified." msgid "AddMember|No users specified."
msgstr "" msgstr ""
...@@ -4919,12 +4928,18 @@ msgstr "" ...@@ -4919,12 +4928,18 @@ msgstr ""
msgid "Could not create group" msgid "Could not create group"
msgstr "" msgstr ""
msgid "Could not create issue"
msgstr ""
msgid "Could not create project" msgid "Could not create project"
msgstr "" msgstr ""
msgid "Could not delete chat nickname %{chat_name}." msgid "Could not delete chat nickname %{chat_name}."
msgstr "" msgstr ""
msgid "Could not fetch projects"
msgstr ""
msgid "Could not remove the trigger." msgid "Could not remove the trigger."
msgstr "" msgstr ""
...@@ -6254,6 +6269,9 @@ msgstr "" ...@@ -6254,6 +6269,9 @@ msgstr ""
msgid "Edit Deploy Key" msgid "Edit Deploy Key"
msgstr "" msgstr ""
msgid "Edit Group Hook"
msgstr ""
msgid "Edit Label" msgid "Edit Label"
msgstr "" msgstr ""
...@@ -6266,12 +6284,18 @@ msgstr "" ...@@ -6266,12 +6284,18 @@ msgstr ""
msgid "Edit Pipeline Schedule %{id}" msgid "Edit Pipeline Schedule %{id}"
msgstr "" msgstr ""
msgid "Edit Project Hook"
msgstr ""
msgid "Edit Release" msgid "Edit Release"
msgstr "" msgstr ""
msgid "Edit Snippet" msgid "Edit Snippet"
msgstr "" msgstr ""
msgid "Edit System Hook"
msgstr ""
msgid "Edit application" msgid "Edit application"
msgstr "" msgstr ""
...@@ -8749,6 +8773,9 @@ msgstr "" ...@@ -8749,6 +8773,9 @@ msgstr ""
msgid "Group Git LFS status:" msgid "Group Git LFS status:"
msgstr "" msgstr ""
msgid "Group Hooks"
msgstr ""
msgid "Group ID" msgid "Group ID"
msgstr "" msgstr ""
...@@ -9896,6 +9923,9 @@ msgstr "" ...@@ -9896,6 +9923,9 @@ msgstr ""
msgid "IssuesAnalytics|Total:" msgid "IssuesAnalytics|Total:"
msgstr "" msgstr ""
msgid "Issue|Title"
msgstr ""
msgid "It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected." msgid "It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected."
msgstr "" msgstr ""
...@@ -11604,6 +11634,9 @@ msgstr "" ...@@ -11604,6 +11634,9 @@ msgstr ""
msgid "New issue" msgid "New issue"
msgstr "" msgstr ""
msgid "New issue title"
msgstr ""
msgid "New label" msgid "New label"
msgstr "" msgstr ""
...@@ -11850,6 +11883,9 @@ msgstr "" ...@@ -11850,6 +11883,9 @@ msgstr ""
msgid "No vulnerabilities present" msgid "No vulnerabilities present"
msgstr "" msgstr ""
msgid "No webhooks found, add one in the form above."
msgstr ""
msgid "No, directly import the existing email addresses and usernames." msgid "No, directly import the existing email addresses and usernames."
msgstr "" msgstr ""
...@@ -13550,6 +13586,9 @@ msgstr "" ...@@ -13550,6 +13586,9 @@ msgstr ""
msgid "Project Files" msgid "Project Files"
msgstr "" msgstr ""
msgid "Project Hooks"
msgstr ""
msgid "Project ID" msgid "Project ID"
msgstr "" msgstr ""
...@@ -15309,7 +15348,7 @@ msgstr "" ...@@ -15309,7 +15348,7 @@ msgstr ""
msgid "SSH public key" msgid "SSH public key"
msgstr "" msgstr ""
msgid "SSL Verification" msgid "SSL Verification:"
msgstr "" msgstr ""
msgid "Saturday" msgid "Saturday"
...@@ -17463,6 +17502,9 @@ msgstr "" ...@@ -17463,6 +17502,9 @@ msgstr ""
msgid "Terms of Service and Privacy Policy" msgid "Terms of Service and Privacy Policy"
msgstr "" msgstr ""
msgid "Test"
msgstr ""
msgid "Test coverage parsing" msgid "Test coverage parsing"
msgstr "" msgstr ""
......
...@@ -81,8 +81,8 @@ module QA ...@@ -81,8 +81,8 @@ module QA
find_element(name, class: 'active') find_element(name, class: 'active')
end end
def all_elements(name) def all_elements(name, **kwargs)
all(element_selector_css(name)) all(element_selector_css(name), **kwargs)
end end
def check_element(name) def check_element(name)
...@@ -206,12 +206,7 @@ module QA ...@@ -206,12 +206,7 @@ module QA
end end
def within_element_by_index(name, index) def within_element_by_index(name, index)
# Finding all elements can be flaky if the elements don't all load page.within all_elements(name, minimum: index + 1)[index] do
# immediately. So we wait for any to appear before trying to find a
# specific one.
has_element?(name)
page.within all_elements(name)[index] do
yield yield
end end
end end
......
...@@ -60,18 +60,35 @@ module QA ...@@ -60,18 +60,35 @@ module QA
element :edit_button element :edit_button
end end
def add_comment_to_diff(text)
wait(interval: 5) do
has_text?("No newline at end of file")
end
all_elements(:new_diff_line).first.hover
click_element :diff_comment
fill_element :reply_input, text
end
def click_discussions_tab def click_discussions_tab
click_element :notes_tab click_element :notes_tab
finished_loading?
end end
def click_diffs_tab def click_diffs_tab
click_element :diffs_tab click_element :diffs_tab
finished_loading?
end end
def click_pipeline_link def click_pipeline_link
click_element :pipeline_link click_element :pipeline_link
end end
def edit!
click_element :edit_button
end
def fast_forward_possible? def fast_forward_possible?
has_no_text?('Fast-forward merge is not possible') has_no_text?('Fast-forward merge is not possible')
end end
...@@ -82,55 +99,6 @@ module QA ...@@ -82,55 +99,6 @@ module QA
has_element?(:merge_button) has_element?(:merge_button)
end end
def has_merge_options?
has_element?(:merge_moment_dropdown)
end
def merged?
has_element? :merged_status_content, text: 'The changes were merged into'
end
def merge_immediately
wait(reload: false) do
finished_loading?
end
if has_merge_options?
retry_until do
click_element :merge_moment_dropdown
has_element? :merge_immediately_option
end
click_element :merge_immediately_option
else
click_element :merge_button
end
wait(reload: false) do
merged?
end
end
def rebase!
# The rebase button is disabled on load
wait do
has_element?(:mr_rebase_button)
end
# The rebase button is enabled via JS
wait(reload: false) do
!find_element(:mr_rebase_button).disabled?
end
click_element :mr_rebase_button
success = wait do
has_text?('Fast-forward merge without a merge commit')
end
raise "Rebase did not appear to be successful" unless success
end
def has_assignee?(username) def has_assignee?(username)
page.within(element_selector_css(:assignee_block)) do page.within(element_selector_css(:assignee_block)) do
has_text?(username) has_text?(username)
...@@ -156,20 +124,6 @@ module QA ...@@ -156,20 +124,6 @@ module QA
has_element?(:description, text: description) has_element?(:description, text: description)
end end
def try_to_merge!
merge_immediately if ready_to_merge?
end
def merge!
try_to_merge!
success = wait do
has_text?('The changes were merged into')
end
raise "Merge did not appear to be successful" unless success
end
def mark_to_squash def mark_to_squash
# The squash checkbox is disabled on load # The squash checkbox is disabled on load
wait do wait do
...@@ -184,17 +138,14 @@ module QA ...@@ -184,17 +138,14 @@ module QA
click_element :squash_checkbox click_element :squash_checkbox
end end
def add_comment_to_diff(text) def merge!
wait(interval: 5) do click_element :merge_button if ready_to_merge?
has_text?("No newline at end of file")
end raise "Merge did not appear to be successful" unless merged?
all_elements(:new_diff_line).first.hover
click_element :diff_comment
fill_element :reply_input, text
end end
def edit! def merged?
click_element :edit_button has_element?(:merged_status_content, text: 'The changes were merged into', wait: 30)
end end
def ready_to_merge? def ready_to_merge?
...@@ -209,6 +160,30 @@ module QA ...@@ -209,6 +160,30 @@ module QA
end end
end end
def rebase!
# The rebase button is disabled on load
wait do
has_element?(:mr_rebase_button)
end
# The rebase button is enabled via JS
wait(reload: false) do
!find_element(:mr_rebase_button).disabled?
end
click_element :mr_rebase_button
success = wait do
has_text?('Fast-forward merge without a merge commit')
end
raise "Rebase did not appear to be successful" unless success
end
def try_to_merge!
click_element :merge_button if ready_to_merge?
end
def view_email_patches def view_email_patches
click_element :dropdown_toggle click_element :dropdown_toggle
visit_link_in_element(:download_email_patches) visit_link_in_element(:download_email_patches)
......
...@@ -48,7 +48,7 @@ module QA ...@@ -48,7 +48,7 @@ module QA
@standalone = false @standalone = false
@description = 'My awesome project' @description = 'My awesome project'
@initialize_with_readme = false @initialize_with_readme = false
@auto_devops_enabled = true @auto_devops_enabled = false
@visibility = 'public' @visibility = 'public'
end end
......
...@@ -49,8 +49,8 @@ module QA ...@@ -49,8 +49,8 @@ module QA
element element
end end
def all_elements(name) def all_elements(name, **kwargs)
log("finding all :#{name}") log("finding all :#{name} with args #{kwargs}")
elements = super elements = super
......
...@@ -85,7 +85,7 @@ describe 'Admin::Hooks' do ...@@ -85,7 +85,7 @@ describe 'Admin::Hooks' do
it 'from hooks list page' do it 'from hooks list page' do
visit admin_hooks_path visit admin_hooks_path
accept_confirm { click_link 'Remove' } accept_confirm { click_link 'Delete' }
expect(page).not_to have_content(hook_url) expect(page).not_to have_content(hook_url)
end end
...@@ -93,7 +93,7 @@ describe 'Admin::Hooks' do ...@@ -93,7 +93,7 @@ describe 'Admin::Hooks' do
visit admin_hooks_path visit admin_hooks_path
click_link 'Edit' click_link 'Edit'
accept_confirm { click_link 'Remove' } accept_confirm { click_link 'Delete' }
expect(page).not_to have_content(hook_url) expect(page).not_to have_content(hook_url)
end end
end end
......
...@@ -89,12 +89,12 @@ describe 'Projects > Settings > Integration settings' do ...@@ -89,12 +89,12 @@ describe 'Projects > Settings > Integration settings' do
expect(current_path).to eq(integrations_path) expect(current_path).to eq(integrations_path)
end end
context 'remove existing webhook' do context 'delete existing webhook' do
it 'from webhooks list page' do it 'from webhooks list page' do
hook hook
visit integrations_path visit integrations_path
expect { click_link 'Remove' }.to change(ProjectHook, :count).by(-1) expect { click_link 'Delete' }.to change(ProjectHook, :count).by(-1)
end end
it 'from webhook edit page' do it 'from webhook edit page' do
...@@ -102,7 +102,7 @@ describe 'Projects > Settings > Integration settings' do ...@@ -102,7 +102,7 @@ describe 'Projects > Settings > Integration settings' do
visit integrations_path visit integrations_path
click_link 'Edit' click_link 'Edit'
expect { click_link 'Remove' }.to change(ProjectHook, :count).by(-1) expect { click_link 'Delete' }.to change(ProjectHook, :count).by(-1)
end end
end end
end end
......
...@@ -99,6 +99,15 @@ ...@@ -99,6 +99,15 @@
"access_level": 50, "access_level": 50,
"notification_level": 3 "notification_level": 3
} }
},
"_links": {
"self": "https://gitlab.com/api/v4/projects/278964",
"issues": "https://gitlab.com/api/v4/projects/278964/issues",
"merge_requests": "https://gitlab.com/api/v4/projects/278964/merge_requests",
"repo_branches": "https://gitlab.com/api/v4/projects/278964/repository/branches",
"labels": "https://gitlab.com/api/v4/projects/278964/labels",
"events": "https://gitlab.com/api/v4/projects/278964/events",
"members": "https://gitlab.com/api/v4/projects/278964/members"
} }
}, { }, {
"id": 7, "id": 7,
......
...@@ -5,20 +5,24 @@ exports[`Repository file preview component renders file HTML 1`] = ` ...@@ -5,20 +5,24 @@ exports[`Repository file preview component renders file HTML 1`] = `
class="file-holder limited-width-container readme-holder" class="file-holder limited-width-container readme-holder"
> >
<div <div
class="file-title" class="js-file-title file-title-flex-parent"
> >
<i <div
aria-hidden="true" class="file-header-content"
class="fa fa-file-text-o fa-fw"
/>
<gllink-stub
href="http://test.com"
> >
<strong> <i
README.md aria-hidden="true"
</strong> class="fa fa-file-text-o fa-fw"
</gllink-stub> />
<gllink-stub
href="http://test.com"
>
<strong>
README.md
</strong>
</gllink-stub>
</div>
</div> </div>
<div <div
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册