Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
e2dcb7987a
commit
08d789003a
38 changed files with 340 additions and 6867 deletions
6712
CHANGELOG-EE.md
6712
CHANGELOG-EE.md
File diff suppressed because it is too large
Load diff
|
@ -7,12 +7,14 @@ import eventHub from '../eventhub';
|
|||
import DeployKeysService from '../service';
|
||||
import DeployKeysStore from '../store';
|
||||
import KeysPanel from './keys_panel.vue';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
KeysPanel,
|
||||
NavigationTabs,
|
||||
GlLoadingIcon,
|
||||
Icon,
|
||||
},
|
||||
props: {
|
||||
endpoint: {
|
||||
|
@ -123,8 +125,8 @@ export default {
|
|||
/>
|
||||
<template v-else-if="hasKeys">
|
||||
<div class="top-area scrolling-tabs-container inner-page-scroll-tabs">
|
||||
<div class="fade-left"><i class="fa fa-angle-left" aria-hidden="true"> </i></div>
|
||||
<div class="fade-right"><i class="fa fa-angle-right" aria-hidden="true"> </i></div>
|
||||
<div class="fade-left"><icon name="chevron-lg-left" :size="12" /></div>
|
||||
<div class="fade-right"><icon name="chevron-lg-right" :size="12" /></div>
|
||||
|
||||
<navigation-tabs :tabs="tabs" scope="deployKeys" @onChangeTab="onChangeTab" />
|
||||
</div>
|
||||
|
|
|
@ -9,6 +9,7 @@ import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
|
|||
import NavigationControls from './nav_controls.vue';
|
||||
import { getParameterByName } from '~/lib/utils/common_utils';
|
||||
import CIPaginationMixin from '~/vue_shared/mixins/ci_pagination_api_mixin';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import PipelinesFilteredSearch from './pipelines_filtered_search.vue';
|
||||
import { validateParams } from '../../utils';
|
||||
import { ANY_TRIGGER_AUTHOR, RAW_TEXT_WARNING, FILTER_TAG_IDENTIFIER } from '../../constants';
|
||||
|
@ -20,6 +21,7 @@ export default {
|
|||
NavigationTabs,
|
||||
NavigationControls,
|
||||
PipelinesFilteredSearch,
|
||||
Icon,
|
||||
},
|
||||
mixins: [pipelinesMixin, CIPaginationMixin, glFeatureFlagsMixin()],
|
||||
props: {
|
||||
|
@ -298,8 +300,8 @@ export default {
|
|||
v-if="shouldRenderTabs || shouldRenderButtons"
|
||||
class="top-area scrolling-tabs-container inner-page-scroll-tabs"
|
||||
>
|
||||
<div class="fade-left"><i class="fa fa-angle-left" aria-hidden="true"> </i></div>
|
||||
<div class="fade-right"><i class="fa fa-angle-right" aria-hidden="true"> </i></div>
|
||||
<div class="fade-left"><icon name="chevron-lg-left" :size="12" /></div>
|
||||
<div class="fade-right"><icon name="chevron-lg-right" :size="12" /></div>
|
||||
|
||||
<navigation-tabs
|
||||
v-if="shouldRenderTabs"
|
||||
|
|
|
@ -137,7 +137,8 @@
|
|||
transition-duration: 0.3s;
|
||||
}
|
||||
|
||||
.fa {
|
||||
.fa,
|
||||
svg {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
font-size: 18px;
|
||||
|
|
|
@ -313,7 +313,7 @@
|
|||
right: 0;
|
||||
text-align: right;
|
||||
|
||||
.fa {
|
||||
svg {
|
||||
right: 5px;
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +323,7 @@
|
|||
left: 0;
|
||||
text-align: left;
|
||||
|
||||
.fa {
|
||||
svg {
|
||||
left: 5px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module BuildsHelper
|
||||
def build_summary(build, skip: false)
|
||||
if build.has_trace?
|
||||
if skip
|
||||
link_to _("View job log"), pipeline_job_url(build.pipeline, build)
|
||||
else
|
||||
build.trace.html(last_lines: 10).html_safe
|
||||
end
|
||||
else
|
||||
_("No job log")
|
||||
end
|
||||
end
|
||||
|
||||
def sidebar_build_class(build, current_build)
|
||||
build_class = []
|
||||
build_class << 'active' if build.id === current_build.id
|
||||
build_class << 'retried' if build.retried?
|
||||
build_class.join(' ')
|
||||
end
|
||||
|
||||
def javascript_build_options
|
||||
{
|
||||
page_path: project_job_path(@project, @build),
|
||||
build_status: @build.status,
|
||||
build_stage: @build.stage,
|
||||
log_state: ''
|
||||
}
|
||||
end
|
||||
|
||||
def build_failed_issue_options
|
||||
{
|
||||
title: _("Job Failed #%{build_id}") % { build_id: @build.id },
|
||||
description: project_job_url(@project, @build)
|
||||
}
|
||||
end
|
||||
end
|
40
app/helpers/ci/builds_helper.rb
Normal file
40
app/helpers/ci/builds_helper.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
module BuildsHelper
|
||||
def build_summary(build, skip: false)
|
||||
if build.has_trace?
|
||||
if skip
|
||||
link_to _('View job log'), pipeline_job_url(build.pipeline, build)
|
||||
else
|
||||
build.trace.html(last_lines: 10).html_safe
|
||||
end
|
||||
else
|
||||
_('No job log')
|
||||
end
|
||||
end
|
||||
|
||||
def sidebar_build_class(build, current_build)
|
||||
build_class = []
|
||||
build_class << 'active' if build.id === current_build.id
|
||||
build_class << 'retried' if build.retried?
|
||||
build_class.join(' ')
|
||||
end
|
||||
|
||||
def javascript_build_options
|
||||
{
|
||||
page_path: project_job_path(@project, @build),
|
||||
build_status: @build.status,
|
||||
build_stage: @build.stage,
|
||||
log_state: ''
|
||||
}
|
||||
end
|
||||
|
||||
def build_failed_issue_options
|
||||
{
|
||||
title: _("Job Failed #%{build_id}") % { build_id: @build.id },
|
||||
description: project_job_url(@project, @build)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
54
app/helpers/ci/variables_helper.rb
Normal file
54
app/helpers/ci/variables_helper.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
module VariablesHelper
|
||||
def ci_variable_protected_by_default?
|
||||
Gitlab::CurrentSettings.current_application_settings.protected_ci_variables
|
||||
end
|
||||
|
||||
def create_deploy_token_path(entity, opts = {})
|
||||
if entity.is_a?(::Group)
|
||||
create_deploy_token_group_settings_repository_path(entity, opts)
|
||||
else
|
||||
# TODO: change this path to 'create_deploy_token_project_settings_ci_cd_path'
|
||||
# See MR comment for more detail: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27059#note_311585356
|
||||
create_deploy_token_project_settings_repository_path(entity, opts)
|
||||
end
|
||||
end
|
||||
|
||||
def revoke_deploy_token_path(entity, token)
|
||||
if entity.is_a?(::Group)
|
||||
revoke_group_deploy_token_path(entity, token)
|
||||
else
|
||||
revoke_project_deploy_token_path(entity, token)
|
||||
end
|
||||
end
|
||||
|
||||
def ci_variable_protected?(variable, only_key_value)
|
||||
if variable && !only_key_value
|
||||
variable.protected
|
||||
else
|
||||
ci_variable_protected_by_default?
|
||||
end
|
||||
end
|
||||
|
||||
def ci_variable_masked?(variable, only_key_value)
|
||||
if variable && !only_key_value
|
||||
variable.masked
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def ci_variable_type_options
|
||||
[
|
||||
%w(Variable env_var),
|
||||
%w(File file)
|
||||
]
|
||||
end
|
||||
|
||||
def ci_variable_maskable_regex
|
||||
Ci::Maskable::REGEX.inspect.sub('\\A', '^').sub('\\z', '$').sub(/^\//, '').sub(/\/[a-z]*$/, '').gsub('\/', '/')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module CiVariablesHelper
|
||||
def ci_variable_protected_by_default?
|
||||
Gitlab::CurrentSettings.current_application_settings.protected_ci_variables
|
||||
end
|
||||
|
||||
def create_deploy_token_path(entity, opts = {})
|
||||
if entity.is_a?(Group)
|
||||
create_deploy_token_group_settings_repository_path(entity, opts)
|
||||
else
|
||||
# TODO: change this path to 'create_deploy_token_project_settings_ci_cd_path'
|
||||
# See MR comment for more detail: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27059#note_311585356
|
||||
create_deploy_token_project_settings_repository_path(entity, opts)
|
||||
end
|
||||
end
|
||||
|
||||
def revoke_deploy_token_path(entity, token)
|
||||
if entity.is_a?(Group)
|
||||
revoke_group_deploy_token_path(entity, token)
|
||||
else
|
||||
revoke_project_deploy_token_path(entity, token)
|
||||
end
|
||||
end
|
||||
|
||||
def ci_variable_protected?(variable, only_key_value)
|
||||
if variable && !only_key_value
|
||||
variable.protected
|
||||
else
|
||||
ci_variable_protected_by_default?
|
||||
end
|
||||
end
|
||||
|
||||
def ci_variable_masked?(variable, only_key_value)
|
||||
if variable && !only_key_value
|
||||
variable.masked
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def ci_variable_type_options
|
||||
[
|
||||
%w(Variable env_var),
|
||||
%w(File file)
|
||||
]
|
||||
end
|
||||
|
||||
def ci_variable_maskable_regex
|
||||
Ci::Maskable::REGEX.inspect.sub('\\A', '^').sub('\\z', '$').sub(/^\//, '').sub(/\/[a-z]*$/, '').gsub('\/', '/')
|
||||
end
|
||||
end
|
|
@ -8,20 +8,19 @@ class Repositories::BaseService < BaseService
|
|||
attr_reader :repository
|
||||
|
||||
delegate :container, :disk_path, :full_path, to: :repository
|
||||
delegate :repository_storage, to: :container
|
||||
|
||||
def initialize(repository)
|
||||
@repository = repository
|
||||
end
|
||||
|
||||
def repo_exists?(path)
|
||||
gitlab_shell.repository_exists?(repository_storage, path + '.git')
|
||||
gitlab_shell.repository_exists?(repository.shard, path + '.git')
|
||||
end
|
||||
|
||||
def mv_repository(from_path, to_path)
|
||||
return true unless repo_exists?(from_path)
|
||||
|
||||
gitlab_shell.mv_repository(repository_storage, from_path, to_path)
|
||||
gitlab_shell.mv_repository(repository.shard, from_path, to_path)
|
||||
end
|
||||
|
||||
# Build a path for removing repositories
|
||||
|
|
|
@ -9,7 +9,7 @@ class Repositories::ShellDestroyService < Repositories::BaseService
|
|||
|
||||
GitlabShellWorker.perform_in(delay,
|
||||
:remove_repository,
|
||||
repository_storage,
|
||||
repository.shard,
|
||||
removal_path)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
|
||||
.fade-left
|
||||
= icon('angle-left')
|
||||
= sprite_icon('chevron-lg-left', size: 12)
|
||||
.fade-right
|
||||
= icon('angle-right')
|
||||
= sprite_icon('chevron-lg-right', size: 12)
|
||||
%ul.nav-links.nav.nav-tabs.scrolling-tabs
|
||||
= nav_link(html_options: { class: active_when(params[:filter].nil?) }) do
|
||||
= link_to admin_users_path do
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
= link_to _("New project"), new_project_path, class: "btn btn-success"
|
||||
|
||||
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
|
||||
.fade-left= icon('angle-left')
|
||||
.fade-right= icon('angle-right')
|
||||
.fade-left= sprite_icon('chevron-lg-left', size: 12)
|
||||
.fade-right= sprite_icon('chevron-lg-right', size: 12)
|
||||
%ul.nav-links.scrolling-tabs.mobile-separator.nav.nav-tabs{ class: ('border-0' if feature_project_list_filter_bar) }
|
||||
= nav_link(page: [dashboard_projects_path, root_path]) do
|
||||
= link_to dashboard_projects_path, class: 'shortcuts-activity', data: {placement: 'right'} do
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
.groups-listing{ data: { endpoints: { default: group_children_path(@group, format: :json), shared: group_shared_projects_path(@group, format: :json) } } }
|
||||
.top-area.group-nav-container.justify-content-between
|
||||
.scrolling-tabs-container.inner-page-scroll-tabs
|
||||
.fade-left= icon('angle-left')
|
||||
.fade-right= icon('angle-right')
|
||||
.fade-left= sprite_icon('chevron-lg-left', size: 12)
|
||||
.fade-right= sprite_icon('chevron-lg-right', size: 12)
|
||||
%ul.nav-links.scrolling-tabs.mobile-separator.nav.nav-tabs
|
||||
%li.js-subgroups_and_projects-tab
|
||||
= link_to group_path, data: { target: 'div#subgroups_and_projects', action: 'subgroups_and_projects', toggle: 'tab'} do
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
.merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
|
||||
.merge-request-tabs-container
|
||||
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
|
||||
.fade-left= icon('angle-left')
|
||||
.fade-right= icon('angle-right')
|
||||
.fade-left= sprite_icon('chevron-lg-left', size: 12)
|
||||
.fade-right= sprite_icon('chevron-lg-right', size: 12)
|
||||
%ul.merge-request-tabs.nav.nav-tabs.nav-links.no-top.no-bottom.js-tabs-affix
|
||||
%li.commits-tab.new-tab
|
||||
= link_to url_for(safe_params), data: {target: 'div#commits', action: 'new', toggle: 'tabvue'} do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- content_for :create_access_levels do
|
||||
.create_access_levels-container
|
||||
.create_access_levels-container{ data: { qa_selector: 'access_levels_content' } }
|
||||
= dropdown_tag('Select',
|
||||
options: { toggle_class: 'js-allowed-to-create wide',
|
||||
dropdown_class: 'dropdown-menu-selectable capitalize-header',
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
= search_filter_link 'users', _("Users")
|
||||
|
||||
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
|
||||
.fade-left= icon('angle-left')
|
||||
.fade-right= icon('angle-right')
|
||||
.fade-left= sprite_icon('chevron-lg-left', size: 12)
|
||||
.fade-right= sprite_icon('chevron-lg-right', size: 12)
|
||||
%ul.nav-links.search-filter.scrolling-tabs.nav.nav-tabs
|
||||
- if @project
|
||||
- if project_search_tabs?(:blobs)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
- show_group_events = local_assigns.fetch(:show_group_events, false)
|
||||
|
||||
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller.flex-fill
|
||||
.fade-left= icon('angle-left')
|
||||
.fade-right= icon('angle-right')
|
||||
.fade-left= sprite_icon('chevron-lg-left', size: 12)
|
||||
.fade-right= sprite_icon('chevron-lg-right', size: 12)
|
||||
%ul.nav-links.event-filter.scrolling-tabs.nav.nav-tabs
|
||||
= event_filter_link EventFilter::ALL, _('All'), s_('EventFilterBy|Filter by all')
|
||||
- if event_filter_visible(:repository)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
|
||||
.fade-left= icon('angle-left')
|
||||
.fade-right= icon('angle-right')
|
||||
.fade-left= sprite_icon('chevron-lg-left', size: 12)
|
||||
.fade-right= sprite_icon('chevron-lg-right', size: 12)
|
||||
%ul.nav-links.scrolling-tabs.js-milestone-tabs.nav.nav-tabs
|
||||
%li.nav-item
|
||||
= link_to '#tab-issues', class: 'nav-link active', data: { toggle: 'tab', show: '.tab-issues-buttons' } do
|
||||
|
|
|
@ -89,8 +89,8 @@
|
|||
|
||||
- unless profile_tabs.empty?
|
||||
.scrolling-tabs-container
|
||||
.fade-left= icon('angle-left')
|
||||
.fade-right= icon('angle-right')
|
||||
.fade-left= sprite_icon('chevron-lg-left', size: 12)
|
||||
.fade-right= sprite_icon('chevron-lg-right', size: 12)
|
||||
%ul.nav-links.user-profile-nav.scrolling-tabs.nav.nav-tabs
|
||||
- if profile_tab?(:overview)
|
||||
%li.js-overview-tab
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Expand healtchecks `500`s when DB is not available
|
||||
merge_request: 34844
|
||||
author:
|
||||
type: fixed
|
|
@ -375,6 +375,8 @@ otherwise the external file won't be included.
|
|||
| [`remote`](#includeremote) | Include a file from a remote URL. Must be publicly accessible. |
|
||||
| [`template`](#includetemplate) | Include templates which are provided by GitLab. |
|
||||
|
||||
The `include` methods do not support [variable expansion](../variables/where_variables_can_be_used.md#variables-usage).
|
||||
|
||||
NOTE: **Note:**
|
||||
`.gitlab-ci.yml` configuration included by all methods is evaluated at pipeline creation.
|
||||
The configuration is a snapshot in time and persisted in the database. Any changes to
|
||||
|
|
|
@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
type: reference
|
||||
---
|
||||
|
||||
# GitLab CI/CD YAML includes
|
||||
# GitLab CI/CD include examples
|
||||
|
||||
In addition to the [`includes` examples](README.md#include) listed in the
|
||||
[GitLab CI YAML reference](README.md), this page lists more variations of `include`
|
||||
|
|
|
@ -111,11 +111,7 @@ Patterns:
|
|||
- `'"((?:\\"|[^"]|\\")*)"'`: captures terms inside quotes, removing the quotes
|
||||
- `"'((?:\\'|[^']|\\')*)'"`: same as above, for single-quotes
|
||||
- `'\.([^.]+)(?=\.|\s|\Z)'`: separate terms with periods in-between
|
||||
- `'\/?([^\/]+)(?=\/|\b)'`: separate path terms `like/this/one`
|
||||
|
||||
#### `edgeNGram_filter`
|
||||
|
||||
Uses an [Edge NGram token filter](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/analysis-edgengram-tokenfilter.html) to allow inputs with only parts of a token to find the token. For example it would turn `glasses` into permutations starting with `gl` and ending with `glasses`, which would allow a search for "`glass`" to find the original token `glasses`
|
||||
- `'([\p{L}_.-]+)'` : some common chars in file names to keep the whole filename intact (eg. `my_file-ñame.txt`)
|
||||
|
||||
## Gotchas
|
||||
|
||||
|
|
|
@ -178,6 +178,10 @@ For example, to add support for files referenced by a `Widget` model with a
|
|||
|
||||
mount_uploader :file, WidgetUploader
|
||||
|
||||
def self.replicables_for_geo_node
|
||||
# Should be implemented. The idea of the method is to restrict
|
||||
# the set of synced items depending on synchronization settings
|
||||
end
|
||||
...
|
||||
end
|
||||
```
|
||||
|
@ -257,19 +261,30 @@ For example, to add support for files referenced by a `Widget` model with a
|
|||
class Geo::WidgetRegistry < Geo::BaseRegistry
|
||||
include Geo::StateMachineRegistry
|
||||
|
||||
MODEL_CLASS = ::Widget
|
||||
MODEL_FOREIGN_KEY = :widget_id
|
||||
|
||||
belongs_to :widget, class_name: 'Widget'
|
||||
|
||||
def self.has_create_events?
|
||||
true
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
The method `has_create_events?` should return `true` in most of the cases.
|
||||
However, if the entity you add doesn't have the create event, don't add the
|
||||
method at all.
|
||||
|
||||
1. Update `REGISTRY_CLASSES` in `ee/app/workers/geo/secondary/registry_consistency_worker.rb`.
|
||||
|
||||
1. Create `ee/spec/factories/geo/widget_registry.rb`:
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :widget_registry, class: 'Geo::WidgetRegistry' do
|
||||
factory :geo_widget_registry, class: 'Geo::WidgetRegistry' do
|
||||
widget
|
||||
state { Geo::WidgetRegistry.state_value(:pending) }
|
||||
|
||||
|
@ -302,13 +317,17 @@ For example, to add support for files referenced by a `Widget` model with a
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Geo::WidgetRegistry, :geo, type: :model do
|
||||
let_it_be(:registry) { create(:widget_registry) }
|
||||
let_it_be(:registry) { create(:geo_widget_registry) }
|
||||
|
||||
specify 'factory is valid' do
|
||||
expect(registry).to be_valid
|
||||
end
|
||||
|
||||
include_examples 'a Geo framework registry'
|
||||
|
||||
describe '.find_registry_differences' do
|
||||
... # To be implemented
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
|
@ -429,7 +448,7 @@ Widgets should now be verified by Geo!
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Resolvers::Geo::WidgetRegistriesResolver do
|
||||
it_behaves_like 'a Geo registries resolver', :widget_registry
|
||||
it_behaves_like 'a Geo registries resolver', :geo_widget_registry
|
||||
end
|
||||
```
|
||||
|
||||
|
@ -453,7 +472,7 @@ Widgets should now be verified by Geo!
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Geo::WidgetRegistryFinder do
|
||||
it_behaves_like 'a framework registry finder', :widget_registry
|
||||
it_behaves_like 'a framework registry finder', :geo_widget_registry
|
||||
end
|
||||
```
|
||||
|
||||
|
@ -503,7 +522,7 @@ Widgets should now be verified by Geo!
|
|||
it_behaves_like 'gets registries for', {
|
||||
field_name: 'widgetRegistries',
|
||||
registry_class_name: 'WidgetRegistry',
|
||||
registry_factory: :widget_registry,
|
||||
registry_factory: :geo_widget_registry,
|
||||
registry_foreign_key_field_name: 'widgetId'
|
||||
}
|
||||
```
|
||||
|
|
|
@ -137,8 +137,8 @@ This check is being exempt from Rack Attack.
|
|||
|
||||
## Access token (Deprecated)
|
||||
|
||||
> NOTE: **Note:**
|
||||
> Access token has been deprecated in GitLab 9.4 in favor of [IP whitelist](#ip-whitelist).
|
||||
NOTE: **Note:**
|
||||
Access token has been deprecated in GitLab 9.4 in favor of [IP whitelist](#ip-whitelist).
|
||||
|
||||
An access token needs to be provided while accessing the probe endpoints. The current
|
||||
accepted token can be found under the **Admin Area > Monitoring > Health check**
|
||||
|
@ -152,6 +152,10 @@ The access token can be passed as a URL parameter:
|
|||
https://gitlab.example.com/-/readiness?token=ACCESS_TOKEN
|
||||
```
|
||||
|
||||
NOTE: **Note:**
|
||||
In case the database or Redis service are unaccessible, the probe endpoints response is not guaranteed to be correct.
|
||||
You should switch to [IP whitelist](#ip-whitelist) from deprecated access token to avoid it.
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
|
|
|
@ -118,8 +118,8 @@ module API
|
|||
|
||||
{
|
||||
repository: repository.gitaly_repository,
|
||||
address: Gitlab::GitalyClient.address(container.repository_storage),
|
||||
token: Gitlab::GitalyClient.token(container.repository_storage),
|
||||
address: Gitlab::GitalyClient.address(repository.shard),
|
||||
token: Gitlab::GitalyClient.token(repository.shard),
|
||||
features: Feature::Gitaly.server_feature_flags
|
||||
}
|
||||
end
|
||||
|
|
|
@ -20,6 +20,12 @@ module Gitlab
|
|||
success ? 200 : 503,
|
||||
status(success).merge(payload(readiness))
|
||||
)
|
||||
rescue => e
|
||||
exception_payload = { message: "#{e.class} : #{e.message}" }
|
||||
|
||||
Probes::Status.new(
|
||||
500,
|
||||
status(false).merge(exception_payload))
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -72,7 +72,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def redis_cluster_validate!(command)
|
||||
RedisClusterValidator.validate!(command) if @redis_cluster_validation
|
||||
::Gitlab::Instrumentation::RedisClusterValidator.validate!(command) if @redis_cluster_validation
|
||||
end
|
||||
|
||||
def enable_redis_cluster_validation
|
||||
|
|
|
@ -216,8 +216,8 @@ module Gitlab
|
|||
|
||||
def gitaly_server_hash(repository)
|
||||
{
|
||||
address: Gitlab::GitalyClient.address(repository.container.repository_storage),
|
||||
token: Gitlab::GitalyClient.token(repository.container.repository_storage),
|
||||
address: Gitlab::GitalyClient.address(repository.shard),
|
||||
token: Gitlab::GitalyClient.token(repository.shard),
|
||||
features: Feature::Gitaly.server_feature_flags
|
||||
}
|
||||
end
|
||||
|
|
1
qa/qa.rb
1
qa/qa.rb
|
@ -183,7 +183,6 @@ module QA
|
|||
autoload :OAuth, 'qa/page/main/oauth'
|
||||
autoload :SignUp, 'qa/page/main/sign_up'
|
||||
autoload :Terms, 'qa/page/main/terms'
|
||||
autoload :Onboarding, 'qa/page/main/onboarding'
|
||||
end
|
||||
|
||||
module Settings
|
||||
|
|
|
@ -165,10 +165,6 @@ module QA
|
|||
terms.accept_terms if terms.visible?
|
||||
end
|
||||
|
||||
QA::Page::Main::Onboarding.perform do |onboarding|
|
||||
onboarding.skip_for_now if onboarding.respond_to?(:skip_for_now) && onboarding.visible?
|
||||
end
|
||||
|
||||
Page::Main::Menu.validate_elements_present! unless skip_page_validation
|
||||
end
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
module Page
|
||||
module Main
|
||||
class Onboarding < Page::Base
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
QA::Page::Main::Onboarding.prepend_if_ee('QA::EE::Page::Main::Onboarding')
|
|
@ -15,7 +15,7 @@ module QA
|
|||
end
|
||||
|
||||
def accept_terms
|
||||
click_element :accept_terms_button
|
||||
click_element :accept_terms_button, Page::Main::Menu
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,6 +12,7 @@ module QA
|
|||
end
|
||||
|
||||
view 'app/views/projects/protected_tags/_create_protected_tag.html.haml' do
|
||||
element :access_levels_content
|
||||
element :access_levels_dropdown
|
||||
end
|
||||
|
||||
|
@ -26,7 +27,9 @@ module QA
|
|||
|
||||
def choose_access_level_role(role)
|
||||
click_element :access_levels_dropdown
|
||||
click_on role
|
||||
within_element(:access_levels_content) do
|
||||
click_on role
|
||||
end
|
||||
end
|
||||
|
||||
def click_protect_tag_button
|
||||
|
|
111
spec/helpers/ci/builds_helper_spec.rb
Normal file
111
spec/helpers/ci/builds_helper_spec.rb
Normal file
|
@ -0,0 +1,111 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::BuildsHelper do
|
||||
describe '#build_summary' do
|
||||
subject { helper.build_summary(build, skip: skip) }
|
||||
|
||||
context 'when build has no trace' do
|
||||
let(:build) { instance_double(Ci::Build, has_trace?: false) }
|
||||
|
||||
context 'when skip is false' do
|
||||
let(:skip) { false }
|
||||
|
||||
it 'returns no job log' do
|
||||
expect(subject).to eq('No job log')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when skip is true' do
|
||||
let(:skip) { true }
|
||||
|
||||
it 'returns no job log' do
|
||||
expect(subject).to eq('No job log')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when build has trace' do
|
||||
let(:build) { create(:ci_build, :trace_live) }
|
||||
|
||||
context 'when skip is true' do
|
||||
let(:skip) { true }
|
||||
|
||||
it 'returns link to logs' do
|
||||
expect(subject).to include('View job log')
|
||||
expect(subject).to include(pipeline_job_url(build.pipeline, build))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when skip is false' do
|
||||
let(:skip) { false }
|
||||
|
||||
it 'returns log lines' do
|
||||
expect(subject).to include(build.trace.html(last_lines: 10).html_safe)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#sidebar_build_class' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:build_id, :current_build_id, :retried, :expected_result) do
|
||||
1 | 1 | true | 'active retried'
|
||||
1 | 1 | false | 'active'
|
||||
1 | 2 | false | ''
|
||||
1 | 2 | true | 'retried'
|
||||
end
|
||||
|
||||
let(:build) { instance_double(Ci::Build, retried?: retried, id: build_id) }
|
||||
let(:current_build) { instance_double(Ci::Build, retried?: true, id: current_build_id ) }
|
||||
|
||||
subject { helper.sidebar_build_class(build, current_build) }
|
||||
|
||||
with_them do
|
||||
it 'builds sidebar html class' do
|
||||
expect(subject).to eq(expected_result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#javascript_build_options' do
|
||||
subject { helper.javascript_build_options }
|
||||
|
||||
it 'returns build options' do
|
||||
project = assign_project
|
||||
ci_build = assign_build
|
||||
|
||||
expect(subject).to eq({
|
||||
page_path: project_job_path(project, ci_build),
|
||||
build_status: ci_build.status,
|
||||
build_stage: ci_build.stage,
|
||||
log_state: ''
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
describe '#build_failed_issue_options' do
|
||||
subject { helper.build_failed_issue_options }
|
||||
|
||||
it 'returns failed title and description' do
|
||||
project = assign_project
|
||||
ci_build = assign_build
|
||||
|
||||
expect(subject).to eq(title: "Job Failed \##{ci_build.id}", description: project_job_url(project, ci_build))
|
||||
end
|
||||
end
|
||||
|
||||
def assign_project
|
||||
build(:project).tap do |project|
|
||||
assign(:project, project)
|
||||
end
|
||||
end
|
||||
|
||||
def assign_build
|
||||
create(:ci_build).tap do |ci_build|
|
||||
assign(:build, ci_build)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -47,6 +47,20 @@ RSpec.describe Gitlab::HealthChecks::Probes::Collection do
|
|||
status: 'failed', message: 'check error')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when check raises exception not handled inside the check' do
|
||||
before do
|
||||
expect(Gitlab::HealthChecks::Redis::RedisCheck).to receive(:readiness).and_raise(
|
||||
::Redis::CannotConnectError, 'Redis down')
|
||||
end
|
||||
|
||||
it 'responds with failure including the exception info' do
|
||||
expect(subject.http_status).to eq(500)
|
||||
|
||||
expect(subject.json[:status]).to eq('failed')
|
||||
expect(subject.json[:message]).to eq('Redis::CannotConnectError : Redis down')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without checks' do
|
||||
|
|
|
@ -129,6 +129,40 @@ RSpec.describe HealthController do
|
|||
expect(response).to have_gitlab_http_status(:service_unavailable)
|
||||
expect(response.headers['X-GitLab-Custom-Error']).to eq(1)
|
||||
end
|
||||
|
||||
context 'when DB is not accessible and connection raises an exception' do
|
||||
before do
|
||||
expect(Gitlab::HealthChecks::DbCheck)
|
||||
.to receive(:readiness)
|
||||
.and_raise(PG::ConnectionBad, 'could not connect to server')
|
||||
end
|
||||
|
||||
it 'responds with 500 including the exception info' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:internal_server_error)
|
||||
expect(response.headers['X-GitLab-Custom-Error']).to eq(1)
|
||||
expect(json_response).to eq(
|
||||
{ 'status' => 'failed', 'message' => 'PG::ConnectionBad : could not connect to server' })
|
||||
end
|
||||
end
|
||||
|
||||
context 'when any exception happens during the probing' do
|
||||
before do
|
||||
expect(Gitlab::HealthChecks::Redis::RedisCheck)
|
||||
.to receive(:readiness)
|
||||
.and_raise(::Redis::CannotConnectError, 'Redis down')
|
||||
end
|
||||
|
||||
it 'responds with 500 including the exception info' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:internal_server_error)
|
||||
expect(response.headers['X-GitLab-Custom-Error']).to eq(1)
|
||||
expect(json_response).to eq(
|
||||
{ 'status' => 'failed', 'message' => 'Redis::CannotConnectError : Redis down' })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue