Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
d9aac35d79
commit
0698388e65
|
@ -1,12 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { escape } from 'lodash';
|
import { escape } from 'lodash';
|
||||||
import { GlDeprecatedButton } from '@gitlab/ui';
|
import { GlButton } from '@gitlab/ui';
|
||||||
import { __, sprintf } from '~/locale';
|
import { __, sprintf } from '~/locale';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
GlDeprecatedButton,
|
GlButton,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
changesEmptyStateIllustration: {
|
changesEmptyStateIllustration: {
|
||||||
|
@ -43,9 +43,9 @@ export default {
|
||||||
<div class="text-content text-center">
|
<div class="text-content text-center">
|
||||||
<span v-html="emptyStateText"></span>
|
<span v-html="emptyStateText"></span>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<gl-deprecated-button :href="getNoteableData.new_blob_path" variant="success">{{
|
<gl-button :href="getNoteableData.new_blob_path" variant="success" category="primary">{{
|
||||||
__('Create commit')
|
__('Create commit')
|
||||||
}}</gl-deprecated-button>
|
}}</gl-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import MrWidgetOptions from 'ee_else_ce/vue_merge_request_widget/mr_widget_options.vue';
|
import MrWidgetOptions from 'ee_else_ce/vue_merge_request_widget/mr_widget_options.vue';
|
||||||
import Translate from '../vue_shared/translate';
|
import Translate from '../vue_shared/translate';
|
||||||
|
import VueApollo from 'vue-apollo';
|
||||||
|
import createDefaultClient from '~/lib/graphql';
|
||||||
|
|
||||||
Vue.use(Translate);
|
Vue.use(Translate);
|
||||||
|
Vue.use(VueApollo);
|
||||||
|
|
||||||
|
const apolloProvider = new VueApollo({
|
||||||
|
defaultClient: createDefaultClient(),
|
||||||
|
});
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
if (gl.mrWidget) return;
|
if (gl.mrWidget) return;
|
||||||
|
@ -10,7 +17,7 @@ export default () => {
|
||||||
gl.mrWidgetData.gitlabLogo = gon.gitlab_logo;
|
gl.mrWidgetData.gitlabLogo = gon.gitlab_logo;
|
||||||
gl.mrWidgetData.defaultAvatarUrl = gon.default_avatar_url;
|
gl.mrWidgetData.defaultAvatarUrl = gon.default_avatar_url;
|
||||||
|
|
||||||
const vm = new Vue(MrWidgetOptions);
|
const vm = new Vue({ ...MrWidgetOptions, apolloProvider });
|
||||||
|
|
||||||
window.gl.mrWidget = {
|
window.gl.mrWidget = {
|
||||||
checkStatus: vm.checkStatus,
|
checkStatus: vm.checkStatus,
|
||||||
|
|
|
@ -360,14 +360,6 @@ table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-button-icon {
|
|
||||||
position: relative;
|
|
||||||
top: 1px;
|
|
||||||
margin-right: $gl-padding-4;
|
|
||||||
color: inherit;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-text {
|
.toolbar-text {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Groups
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json do
|
format.json do
|
||||||
render status: :ok, json: { variables: GroupVariableSerializer.new.represent(@group.variables) }
|
render status: :ok, json: { variables: ::Ci::GroupVariableSerializer.new.represent(@group.variables) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -29,7 +29,7 @@ module Groups
|
||||||
private
|
private
|
||||||
|
|
||||||
def render_group_variables
|
def render_group_variables
|
||||||
render status: :ok, json: { variables: GroupVariableSerializer.new.represent(@group.variables) }
|
render status: :ok, json: { variables: ::Ci::GroupVariableSerializer.new.represent(@group.variables) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_error
|
def render_error
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Projects
|
||||||
|
module IncidentManagement
|
||||||
|
class PagerDutyIncidentsController < Projects::ApplicationController
|
||||||
|
respond_to :json
|
||||||
|
|
||||||
|
skip_before_action :verify_authenticity_token
|
||||||
|
skip_before_action :project
|
||||||
|
|
||||||
|
prepend_before_action :project_without_auth
|
||||||
|
|
||||||
|
def create
|
||||||
|
result = ServiceResponse.success(http_status: :accepted)
|
||||||
|
|
||||||
|
unless Feature.enabled?(:pagerduty_webhook, @project)
|
||||||
|
result = ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized)
|
||||||
|
end
|
||||||
|
|
||||||
|
head result.http_status
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def project_without_auth
|
||||||
|
@project ||= Project
|
||||||
|
.find_by_full_path("#{params[:namespace_id]}/#{params[:project_id]}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,29 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Projects
|
||||||
|
module Pipelines
|
||||||
|
class StagesController < Projects::Pipelines::ApplicationController
|
||||||
|
before_action :authorize_update_pipeline!
|
||||||
|
|
||||||
|
def play_manual
|
||||||
|
::Ci::PlayManualStageService
|
||||||
|
.new(@project, current_user, pipeline: pipeline)
|
||||||
|
.execute(stage)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json do
|
||||||
|
render json: StageSerializer
|
||||||
|
.new(project: @project, current_user: @current_user)
|
||||||
|
.represent(stage)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def stage
|
||||||
|
@pipeline_stage ||= pipeline.find_stage_by_name!(params[:stage_name])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,25 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Projects::StagesController < Projects::PipelinesController
|
|
||||||
before_action :authorize_update_pipeline!
|
|
||||||
|
|
||||||
def play_manual
|
|
||||||
::Ci::PlayManualStageService
|
|
||||||
.new(@project, current_user, pipeline: pipeline)
|
|
||||||
.execute(stage)
|
|
||||||
|
|
||||||
respond_to do |format|
|
|
||||||
format.json do
|
|
||||||
render json: StageSerializer
|
|
||||||
.new(project: @project, current_user: @current_user)
|
|
||||||
.represent(stage)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def stage
|
|
||||||
@pipeline_stage ||= pipeline.find_stage_by_name!(params[:stage_name])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -6,7 +6,7 @@ class Projects::VariablesController < Projects::ApplicationController
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json do
|
format.json do
|
||||||
render status: :ok, json: { variables: VariableSerializer.new.represent(@project.variables) }
|
render status: :ok, json: { variables: ::Ci::VariableSerializer.new.represent(@project.variables) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -26,7 +26,7 @@ class Projects::VariablesController < Projects::ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def render_variables
|
def render_variables
|
||||||
render status: :ok, json: { variables: VariableSerializer.new.represent(@project.variables) }
|
render status: :ok, json: { variables: ::Ci::VariableSerializer.new.represent(@project.variables) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_error
|
def render_error
|
||||||
|
|
|
@ -53,6 +53,15 @@ module IconsHelper
|
||||||
content_tag(:svg, content_tag(:use, "", { "xlink:href" => "#{sprite_icon_path}##{icon_name}" } ), class: css_classes.empty? ? nil : css_classes.join(' '))
|
content_tag(:svg, content_tag(:use, "", { "xlink:href" => "#{sprite_icon_path}##{icon_name}" } ), class: css_classes.empty? ? nil : css_classes.join(' '))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def loading_icon(container: false, color: 'orange', size: 'sm', css_class: nil)
|
||||||
|
css_classes = ['gl-spinner', "gl-spinner-#{color}", "gl-spinner-#{size}"]
|
||||||
|
css_classes << "#{css_class}" unless css_class.blank?
|
||||||
|
|
||||||
|
spinner = content_tag(:span, "", { class: css_classes.join(' '), aria: { label: _('Loading') } })
|
||||||
|
|
||||||
|
container == true ? content_tag(:div, spinner, { class: 'gl-spinner-container' }) : spinner
|
||||||
|
end
|
||||||
|
|
||||||
def external_snippet_icon(name)
|
def external_snippet_icon(name)
|
||||||
content_tag(:span, "", class: "gl-snippet-icon gl-snippet-icon-#{name}")
|
content_tag(:span, "", class: "gl-snippet-icon gl-snippet-icon-#{name}")
|
||||||
end
|
end
|
||||||
|
|
|
@ -57,7 +57,7 @@ module AlertManagement
|
||||||
validates :started_at, presence: true
|
validates :started_at, presence: true
|
||||||
validates :fingerprint, allow_blank: true, uniqueness: {
|
validates :fingerprint, allow_blank: true, uniqueness: {
|
||||||
scope: :project,
|
scope: :project,
|
||||||
conditions: -> { where.not(status: STATUSES[:resolved]) },
|
conditions: -> { not_resolved },
|
||||||
message: -> (object, data) { _('Cannot have multiple unresolved alerts') }
|
message: -> (object, data) { _('Cannot have multiple unresolved alerts') }
|
||||||
}, unless: :resolved?
|
}, unless: :resolved?
|
||||||
validate :hosts_length
|
validate :hosts_length
|
||||||
|
@ -120,6 +120,7 @@ module AlertManagement
|
||||||
scope :for_environment, -> (environment) { where(environment: environment) }
|
scope :for_environment, -> (environment) { where(environment: environment) }
|
||||||
scope :search, -> (query) { fuzzy_search(query, [:title, :description, :monitoring_tool, :service]) }
|
scope :search, -> (query) { fuzzy_search(query, [:title, :description, :monitoring_tool, :service]) }
|
||||||
scope :open, -> { with_status(:triggered, :acknowledged) }
|
scope :open, -> { with_status(:triggered, :acknowledged) }
|
||||||
|
scope :not_resolved, -> { where.not(status: STATUSES[:resolved]) }
|
||||||
scope :with_prometheus_alert, -> { includes(:prometheus_alert) }
|
scope :with_prometheus_alert, -> { includes(:prometheus_alert) }
|
||||||
|
|
||||||
scope :order_start_time, -> (sort_order) { order(started_at: sort_order) }
|
scope :order_start_time, -> (sort_order) { order(started_at: sort_order) }
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Projects
|
||||||
RESERVED_ANNOTATIONS = %w(gitlab_incident_markdown gitlab_y_label title).freeze
|
RESERVED_ANNOTATIONS = %w(gitlab_incident_markdown gitlab_y_label title).freeze
|
||||||
GENERIC_ALERT_SUMMARY_ANNOTATIONS = %w(monitoring_tool service hosts).freeze
|
GENERIC_ALERT_SUMMARY_ANNOTATIONS = %w(monitoring_tool service hosts).freeze
|
||||||
MARKDOWN_LINE_BREAK = " \n".freeze
|
MARKDOWN_LINE_BREAK = " \n".freeze
|
||||||
INCIDENT_LABEL_NAME = IncidentManagement::CreateIncidentLabelService::LABEL_PROPERTIES[:title].freeze
|
INCIDENT_LABEL_NAME = ::IncidentManagement::CreateIncidentLabelService::LABEL_PROPERTIES[:title].freeze
|
||||||
METRIC_TIME_WINDOW = 30.minutes
|
METRIC_TIME_WINDOW = 30.minutes
|
||||||
|
|
||||||
def full_title
|
def full_title
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Ci
|
||||||
|
class GroupVariableEntity < Ci::BasicVariableEntity
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Ci
|
||||||
|
class GroupVariableSerializer < BaseSerializer
|
||||||
|
entity ::Ci::GroupVariableEntity
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Ci
|
||||||
|
class VariableEntity < Ci::BasicVariableEntity
|
||||||
|
expose :environment_scope
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Ci
|
||||||
|
class VariableSerializer < BaseSerializer
|
||||||
|
entity ::Ci::VariableEntity
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class GroupVariableEntity < Ci::BasicVariableEntity
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class GroupVariableSerializer < BaseSerializer
|
|
||||||
entity GroupVariableEntity
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class VariableEntity < Ci::BasicVariableEntity
|
|
||||||
expose :environment_scope
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class VariableSerializer < BaseSerializer
|
|
||||||
entity VariableEntity
|
|
||||||
end
|
|
|
@ -94,7 +94,7 @@ module AlertManagement
|
||||||
end
|
end
|
||||||
|
|
||||||
def am_alert
|
def am_alert
|
||||||
@am_alert ||= AlertManagement::Alert.for_fingerprint(project, gitlab_fingerprint).first
|
@am_alert ||= AlertManagement::Alert.not_resolved.for_fingerprint(project, gitlab_fingerprint).first
|
||||||
end
|
end
|
||||||
|
|
||||||
def bad_request
|
def bad_request
|
||||||
|
|
|
@ -4,7 +4,7 @@ module Projects
|
||||||
module Alerting
|
module Alerting
|
||||||
class NotifyService < BaseService
|
class NotifyService < BaseService
|
||||||
include Gitlab::Utils::StrongMemoize
|
include Gitlab::Utils::StrongMemoize
|
||||||
include IncidentManagement::Settings
|
include ::IncidentManagement::Settings
|
||||||
|
|
||||||
def execute(token)
|
def execute(token)
|
||||||
return forbidden unless alerts_service_activated?
|
return forbidden unless alerts_service_activated?
|
||||||
|
@ -55,7 +55,7 @@ module Projects
|
||||||
def find_alert_by_fingerprint(fingerprint)
|
def find_alert_by_fingerprint(fingerprint)
|
||||||
return unless fingerprint
|
return unless fingerprint
|
||||||
|
|
||||||
AlertManagement::Alert.for_fingerprint(project, fingerprint).first
|
AlertManagement::Alert.not_resolved.for_fingerprint(project, fingerprint).first
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_email?
|
def send_email?
|
||||||
|
@ -65,7 +65,7 @@ module Projects
|
||||||
def process_incident_issues(alert)
|
def process_incident_issues(alert)
|
||||||
return if alert.issue
|
return if alert.issue
|
||||||
|
|
||||||
IncidentManagement::ProcessAlertWorker.perform_async(nil, nil, alert.id)
|
::IncidentManagement::ProcessAlertWorker.perform_async(nil, nil, alert.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_alert_email
|
def send_alert_email
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Projects
|
||||||
module Alerts
|
module Alerts
|
||||||
class NotifyService < BaseService
|
class NotifyService < BaseService
|
||||||
include Gitlab::Utils::StrongMemoize
|
include Gitlab::Utils::StrongMemoize
|
||||||
include IncidentManagement::Settings
|
include ::IncidentManagement::Settings
|
||||||
|
|
||||||
# This set of keys identifies a payload as a valid Prometheus
|
# This set of keys identifies a payload as a valid Prometheus
|
||||||
# payload and thus processable by this service. See also
|
# payload and thus processable by this service. See also
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
%span.attaching-file-message
|
%span.attaching-file-message
|
||||||
-# Populated by app/assets/javascripts/dropzone_input.js
|
-# Populated by app/assets/javascripts/dropzone_input.js
|
||||||
%span.uploading-progress 0%
|
%span.uploading-progress 0%
|
||||||
%span.uploading-spinner
|
= loading_icon(css_class: 'align-text-bottom gl-mr-2')
|
||||||
.toolbar-button-icon.spinner.align-text-top
|
|
||||||
|
|
||||||
%span.uploading-error-container.hide
|
%span.uploading-error-container.hide
|
||||||
%span.uploading-error-icon
|
%span.uploading-error-icon
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Support fenced code blocks in Atlassian Document Format converter
|
||||||
|
merge_request: 35065
|
||||||
|
author:
|
||||||
|
type: fixed
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Open new alert when existing alert is resolved
|
||||||
|
merge_request: 36261
|
||||||
|
author:
|
||||||
|
type: added
|
|
@ -22,10 +22,8 @@ resources :pipelines, only: [:index, :new, :create, :show, :destroy] do
|
||||||
get :test_reports_count
|
get :test_reports_count
|
||||||
end
|
end
|
||||||
|
|
||||||
member do
|
resources :stages, only: [], param: :name, controller: 'pipelines/stages' do
|
||||||
resources :stages, only: [], param: :name do
|
post :play_manual
|
||||||
post :play_manual
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :tests, only: [:show], param: :suite_name, controller: 'pipelines/tests' do
|
resources :tests, only: [:show], param: :suite_name, controller: 'pipelines/tests' do
|
||||||
|
|
|
@ -406,6 +406,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
|
||||||
|
|
||||||
post 'alerts/notify', to: 'alerting/notifications#create'
|
post 'alerts/notify', to: 'alerting/notifications#create'
|
||||||
|
|
||||||
|
post 'incident_management/pager_duty', to: 'incident_management/pager_duty_incidents#create'
|
||||||
|
|
||||||
draw :legacy_builds
|
draw :legacy_builds
|
||||||
|
|
||||||
resources :hooks, only: [:index, :create, :edit, :update, :destroy], constraints: { id: /\d+/ } do # rubocop: disable Cop/PutProjectRoutesUnderScope
|
resources :hooks, only: [:index, :create, :edit, :update, :destroy], constraints: { id: /\d+/ } do # rubocop: disable Cop/PutProjectRoutesUnderScope
|
||||||
|
|
|
@ -21,6 +21,7 @@ exceptions:
|
||||||
- CLI
|
- CLI
|
||||||
- CNAME
|
- CNAME
|
||||||
- CPU
|
- CPU
|
||||||
|
- CORE
|
||||||
- CSS
|
- CSS
|
||||||
- CSV
|
- CSV
|
||||||
- DNS
|
- DNS
|
||||||
|
|
|
@ -11,11 +11,11 @@ level: warning
|
||||||
nonword: true
|
nonword: true
|
||||||
ignorecase: true
|
ignorecase: true
|
||||||
tokens:
|
tokens:
|
||||||
- "GitLab 2."
|
- "GitLab (v)?2."
|
||||||
- "GitLab 3."
|
- "GitLab (v)?3."
|
||||||
- "GitLab 4."
|
- "GitLab (v)?4."
|
||||||
- "GitLab 5."
|
- "GitLab (v)?5."
|
||||||
- "GitLab 6."
|
- "GitLab (v)?6."
|
||||||
- "GitLab 7."
|
- "GitLab (v)?7."
|
||||||
- "GitLab 8."
|
- "GitLab (v)?8."
|
||||||
- "GitLab 9."
|
- "GitLab (v)?9."
|
||||||
|
|
|
@ -140,7 +140,7 @@ The following API resources are available outside of project and group contexts
|
||||||
| [Notification settings](notification_settings.md) | `/notification_settings` (also available for groups and projects) |
|
| [Notification settings](notification_settings.md) | `/notification_settings` (also available for groups and projects) |
|
||||||
| [Pages domains](pages_domains.md) | `/pages/domains` (also available for projects) |
|
| [Pages domains](pages_domains.md) | `/pages/domains` (also available for projects) |
|
||||||
| [Projects](projects.md) | `/users/:id/projects` (also available for projects) |
|
| [Projects](projects.md) | `/users/:id/projects` (also available for projects) |
|
||||||
| [Project Repository Storage Moves](project_repository_storage_moves.md) | `/project_repository_storage_moves` |
|
| [Project repository storage moves](project_repository_storage_moves.md) **(CORE ONLY)** | `/project_repository_storage_moves` |
|
||||||
| [Runners](runners.md) | `/runners` (also available for projects) |
|
| [Runners](runners.md) | `/runners` (also available for projects) |
|
||||||
| [Search](search.md) | `/search` (also available for groups and projects) |
|
| [Search](search.md) | `/search` (also available for groups and projects) |
|
||||||
| [Settings](settings.md) **(CORE ONLY)** | `/application/settings` |
|
| [Settings](settings.md) **(CORE ONLY)** | `/application/settings` |
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
---
|
||||||
|
stage: Release
|
||||||
|
group: Release Management
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
type: concepts, howto
|
||||||
|
---
|
||||||
|
|
||||||
# Deployments API
|
# Deployments API
|
||||||
|
|
||||||
## List project deployments
|
## List project deployments
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
---
|
||||||
|
stage: Release
|
||||||
|
group: Release Management
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
type: concepts, howto
|
||||||
|
---
|
||||||
|
|
||||||
# Environments API
|
# Environments API
|
||||||
|
|
||||||
## List environments
|
## List environments
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
---
|
||||||
|
stage: Monitor
|
||||||
|
group: Health
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
---
|
||||||
|
|
||||||
# Error Tracking settings API
|
# Error Tracking settings API
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34940) in GitLab 12.7.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34940) in GitLab 12.7.
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
---
|
||||||
|
stage: Release
|
||||||
|
group: Release Management
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
type: concepts, howto
|
||||||
|
---
|
||||||
|
|
||||||
# Freeze Periods API
|
# Freeze Periods API
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29382) in GitLab 13.0.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29382) in GitLab 13.0.
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
---
|
||||||
|
stage: Configure
|
||||||
|
group: Configure
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
---
|
||||||
|
|
||||||
# Group clusters API
|
# Group clusters API
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30213) in GitLab 12.1.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30213) in GitLab 12.1.
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
---
|
||||||
|
stage: Monitor
|
||||||
|
group: APM
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
type: concepts, howto
|
||||||
|
---
|
||||||
|
|
||||||
# Dashboard annotations API
|
# Dashboard annotations API
|
||||||
|
|
||||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29089) in GitLab 12.10 behind a disabled feature flag.
|
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29089) in GitLab 12.10 behind a disabled feature flag.
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
---
|
||||||
|
stage: Monitor
|
||||||
|
group: APM
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
type: concepts, howto
|
||||||
|
---
|
||||||
|
|
||||||
# User-starred metrics dashboards API
|
# User-starred metrics dashboards API
|
||||||
|
|
||||||
The starred dashboard feature makes navigating to frequently-used dashboards easier
|
The starred dashboard feature makes navigating to frequently-used dashboards easier
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
---
|
||||||
|
stage: Configure
|
||||||
|
group: Configure
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
---
|
||||||
|
|
||||||
# Project clusters API
|
# Project clusters API
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/23922) in GitLab 11.7.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/23922) in GitLab 11.7.
|
||||||
|
|
|
@ -5,11 +5,12 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
type: reference
|
type: reference
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project repository storage move API
|
# Project repository storage moves API **(CORE ONLY)**
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31285) in GitLab 13.0.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31285) in GitLab 13.0.
|
||||||
|
|
||||||
Project repository storage can be moved. To retrieve project repository storage moves using the API, you must [authenticate yourself](README.md#authentication) as an administrator.
|
Project repository storage can be moved. To retrieve project repository storage moves using the API,
|
||||||
|
you must [authenticate yourself](README.md#authentication) as an administrator.
|
||||||
|
|
||||||
## Retrieve all project repository storage moves
|
## Retrieve all project repository storage moves
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ are [paginated](README.md#pagination).
|
||||||
Example request:
|
Example request:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/project_repository_storage_moves'
|
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/project_repository_storage_moves"
|
||||||
```
|
```
|
||||||
|
|
||||||
Example response:
|
Example response:
|
||||||
|
@ -66,7 +67,7 @@ Parameters:
|
||||||
Example request:
|
Example request:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/1/repository_storage_moves'
|
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/repository_storage_moves"
|
||||||
```
|
```
|
||||||
|
|
||||||
Example response:
|
Example response:
|
||||||
|
@ -106,7 +107,7 @@ Parameters:
|
||||||
Example request:
|
Example request:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/project_repository_storage_moves/1'
|
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/project_repository_storage_moves/1"
|
||||||
```
|
```
|
||||||
|
|
||||||
Example response:
|
Example response:
|
||||||
|
@ -145,7 +146,7 @@ Parameters:
|
||||||
Example request:
|
Example request:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/projects/1/repository_storage_moves/1'
|
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/repository_storage_moves/1"
|
||||||
```
|
```
|
||||||
|
|
||||||
Example response:
|
Example response:
|
||||||
|
@ -185,7 +186,7 @@ Example request:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl --request POST --header "PRIVATE_TOKEN: <your_access_token>" --header "Content-Type: application/json" \
|
curl --request POST --header "PRIVATE_TOKEN: <your_access_token>" --header "Content-Type: application/json" \
|
||||||
--data '{"destination_storage_name":"storage2"}' 'https://gitlab.example.com/api/v4/projects/1/repository_storage_moves'
|
--data '{"destination_storage_name":"storage2"}' "https://gitlab.example.com/api/v4/projects/1/repository_storage_moves"
|
||||||
```
|
```
|
||||||
|
|
||||||
Example response:
|
Example response:
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
---
|
||||||
|
stage: Release
|
||||||
|
group: Release Management
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
type: concepts, howto
|
||||||
|
---
|
||||||
|
|
||||||
# Protected environments API **(PREMIUM)**
|
# Protected environments API **(PREMIUM)**
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30595) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30595) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.8.
|
||||||
|
|
|
@ -963,8 +963,8 @@ a corresponding cluster type. The default value is blank. You can
|
||||||
check the recommended variables for each cluster type in the official
|
check the recommended variables for each cluster type in the official
|
||||||
documentation:
|
documentation:
|
||||||
|
|
||||||
- [Google GKE](https://cilium.readthedocs.io/en/stable/gettingstarted/k8s-install-gke/#prepare-deploy-cilium)
|
- [Google GKE](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-gke/#deploy-cilium)
|
||||||
- [AWS EKS](https://cilium.readthedocs.io/en/stable/gettingstarted/k8s-install-eks/#prepare-deploy-cilium)
|
- [AWS EKS](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-eks/#deploy-cilium)
|
||||||
|
|
||||||
You can customize Cilium's Helm variables by defining the
|
You can customize Cilium's Helm variables by defining the
|
||||||
`.gitlab/managed-apps/cilium/values.yaml` file in your cluster
|
`.gitlab/managed-apps/cilium/values.yaml` file in your cluster
|
||||||
|
@ -974,9 +974,9 @@ for the available configuration options.
|
||||||
|
|
||||||
CAUTION: **Caution:**
|
CAUTION: **Caution:**
|
||||||
Installation and removal of the Cilium requires a **manual**
|
Installation and removal of the Cilium requires a **manual**
|
||||||
[restart](https://cilium.readthedocs.io/en/stable/gettingstarted/k8s-install-gke/#restart-remaining-pods)
|
[restart](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-gke/#restart-unmanaged-pods)
|
||||||
of all affected pods in all namespaces to ensure that they are
|
of all affected pods in all namespaces to ensure that they are
|
||||||
[managed](https://cilium.readthedocs.io/en/stable/troubleshooting/#ensure-pod-is-managed-by-cilium)
|
[managed](https://docs.cilium.io/en/stable/troubleshooting/#ensure-pod-is-managed-by-cilium)
|
||||||
by the correct networking plugin.
|
by the correct networking plugin.
|
||||||
|
|
||||||
NOTE: **Note:**
|
NOTE: **Note:**
|
||||||
|
|
|
@ -101,4 +101,6 @@ displays a counter on the
|
||||||
[Alert Management List](../operations/alert_management.md#alert-management-list)
|
[Alert Management List](../operations/alert_management.md#alert-management-list)
|
||||||
and details pages.
|
and details pages.
|
||||||
|
|
||||||
|
If the existing alert is already `resolved`, then a new alert will be created instead.
|
||||||
|
|
||||||
![Alert Management List](../operations/img/alert_list_v13_1.png)
|
![Alert Management List](../operations/img/alert_list_v13_1.png)
|
||||||
|
|
|
@ -18,7 +18,7 @@ module Gitlab
|
||||||
def action_path
|
def action_path
|
||||||
pipeline = subject.pipeline
|
pipeline = subject.pipeline
|
||||||
|
|
||||||
project_stage_play_manual_path(pipeline.project, pipeline, subject.name)
|
project_pipeline_stage_play_manual_path(pipeline.project, pipeline, subject.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def action_method
|
def action_method
|
||||||
|
|
|
@ -12,6 +12,46 @@ module Kramdown
|
||||||
# Note: this is only an initial implementation. Currently don't
|
# Note: this is only an initial implementation. Currently don't
|
||||||
# strip out IALs or other specific kramdown syntax.
|
# strip out IALs or other specific kramdown syntax.
|
||||||
class Commonmark < ::Kramdown::Converter::Kramdown
|
class Commonmark < ::Kramdown::Converter::Kramdown
|
||||||
|
# replaces the ^ used in kramdown. This forces the current
|
||||||
|
# block to end, so that a different list or codeblock can be
|
||||||
|
# started. https://kramdown.gettalong.org/syntax.html#eob-marker
|
||||||
|
END_OF_BLOCK = '<!-- -->'
|
||||||
|
|
||||||
|
def convert(el, opts = { indent: 0 })
|
||||||
|
res = super
|
||||||
|
|
||||||
|
if [:ul, :dl, :ol, :codeblock].include?(el.type) && opts[:next] &&
|
||||||
|
([el.type, :codeblock].include?(opts[:next].type) ||
|
||||||
|
(opts[:next].type == :blank && opts[:nnext] &&
|
||||||
|
[el.type, :codeblock].include?(opts[:nnext].type)))
|
||||||
|
# replace the end of block character
|
||||||
|
res.sub!(/\^\n\n\z/m, "#{END_OF_BLOCK}\n\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_codeblock(el, _opts)
|
||||||
|
# Although tildes are supported in CommonMark, backticks are more common
|
||||||
|
"```#{el.options[:lang]}\n" +
|
||||||
|
el.value.split(/\n/).map {|l| l.empty? ? "" : "#{l}" }.join("\n") +
|
||||||
|
"\n```\n\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_li(el, opts)
|
||||||
|
res = super
|
||||||
|
|
||||||
|
if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent]
|
||||||
|
if el.children.size == 1 && @stack.last.children.last == el &&
|
||||||
|
(@stack.last.children.any? {|c| c.children.first.type != :p } || @stack.last.children.size == 1)
|
||||||
|
# replace the end of block character
|
||||||
|
res.sub!(/\^\n\z/m, "#{END_OF_BLOCK}\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
def convert_table(el, opts)
|
def convert_table(el, opts)
|
||||||
return super unless @options[:html_tables]
|
return super unless @options[:html_tables]
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,11 @@ msgstr ""
|
||||||
msgid "\"%{path}\" did not exist on \"%{ref}\""
|
msgid "\"%{path}\" did not exist on \"%{ref}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "%d Scanned URL"
|
||||||
|
msgid_plural "%d Scanned URLs"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
msgid "%d URL scanned"
|
msgid "%d URL scanned"
|
||||||
msgid_plural "%d URLs scanned"
|
msgid_plural "%d URLs scanned"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
|
@ -8305,6 +8310,9 @@ msgstr ""
|
||||||
msgid "Download as"
|
msgid "Download as"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Download as CSV"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download asset"
|
msgid "Download asset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -24515,6 +24523,9 @@ msgstr ""
|
||||||
msgid "To this GitLab instance"
|
msgid "To this GitLab instance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "To view all %{scannedResourcesCount} scanned URLs, please download the CSV file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "To view the roadmap, add a start or due date to one of your epics in this group or its subgroups. In the months view, only epics in the past month, current month, and next 5 months are shown."
|
msgid "To view the roadmap, add a start or due date to one of your epics in this group or its subgroups. In the months view, only epics in the past month, current month, and next 5 months are shown."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe Projects::IncidentManagement::PagerDutyIncidentsController do
|
||||||
|
let_it_be(:project) { create(:project) }
|
||||||
|
|
||||||
|
describe 'POST #create' do
|
||||||
|
let(:payload) { { messages: [] } }
|
||||||
|
|
||||||
|
def make_request
|
||||||
|
post :create, params: project_params, body: payload.to_json, as: :json
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when pagerduty_webhook feature enabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(pagerduty_webhook: project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'responds with 202 Accepted' do
|
||||||
|
make_request
|
||||||
|
|
||||||
|
expect(response).to have_gitlab_http_status(:accepted)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when pagerduty_webhook feature disabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(pagerduty_webhook: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'responds with 401 Unauthorized' do
|
||||||
|
make_request
|
||||||
|
|
||||||
|
expect(response).to have_gitlab_http_status(:unauthorized)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def project_params(opts = {})
|
||||||
|
opts.reverse_merge(namespace_id: project.namespace, project_id: project)
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe Projects::StagesController do
|
RSpec.describe Projects::Pipelines::StagesController do
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:project) { create(:project, :repository) }
|
let(:project) { create(:project, :repository) }
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ RSpec.describe Projects::StagesController do
|
||||||
post :play_manual, params: {
|
post :play_manual, params: {
|
||||||
namespace_id: project.namespace,
|
namespace_id: project.namespace,
|
||||||
project_id: project,
|
project_id: project,
|
||||||
id: pipeline.id,
|
pipeline_id: pipeline.id,
|
||||||
stage_name: stage_name
|
stage_name: stage_name
|
||||||
}, format: :json
|
}, format: :json
|
||||||
end
|
end
|
|
@ -14,6 +14,18 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "codeBlock",
|
||||||
|
"attrs": {
|
||||||
|
"language": "css"
|
||||||
|
},
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"text": ".overflow { overflow: hidden; }"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "bulletList",
|
"type": "bulletList",
|
||||||
"content": [
|
"content": [
|
||||||
|
@ -37,6 +49,37 @@
|
||||||
"text": "public DemoClass()\n{\n // assign default value\n x = 0;\n}"
|
"text": "public DemoClass()\n{\n // assign default value\n x = 0;\n}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "orderedList",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "listItem",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "paragraph",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"text": "Number list Item 1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "codeBlock",
|
||||||
|
"attrs": {
|
||||||
|
"language": "ruby"
|
||||||
|
},
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"text": "def test\n # assign default value\n x = 0\nend"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,38 @@
|
||||||
export function makeIssue({ parentIssue, project, users }) {
|
```javascript
|
||||||
|
export function makeIssue({ parentIssue, project, users }) {
|
||||||
const issueType = pickRandom(project.issueTypes)
|
|
||||||
|
const issueType = pickRandom(project.issueTypes)
|
||||||
console.log(data)
|
|
||||||
|
console.log(data)
|
||||||
return data
|
|
||||||
}
|
return data
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
```css
|
||||||
|
.overflow { overflow: hidden; }
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
* Item 1
|
* Item 1
|
||||||
|
|
||||||
public DemoClass()
|
```java
|
||||||
{
|
public DemoClass()
|
||||||
// assign default value
|
{
|
||||||
x = 0;
|
// assign default value
|
||||||
}
|
x = 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
1. Number list Item 1
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
def test
|
||||||
|
# assign default value
|
||||||
|
x = 0
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -165,37 +165,40 @@ Col 3 Row 3
|
||||||
|
|
||||||
<del>Strikethrough</del>
|
<del>Strikethrough</del>
|
||||||
|
|
||||||
export function makeIssue({ parentIssue, project, users }) {
|
```javascript
|
||||||
|
export function makeIssue({ parentIssue, project, users }) {
|
||||||
const issueType = pickRandom(project.issueTypes)
|
|
||||||
|
const issueType = pickRandom(project.issueTypes)
|
||||||
let data = {
|
|
||||||
fields: {
|
let data = {
|
||||||
summary: faker.lorem.sentence(),
|
fields: {
|
||||||
issuetype: {
|
summary: faker.lorem.sentence(),
|
||||||
id: issueType.id
|
issuetype: {
|
||||||
},
|
id: issueType.id
|
||||||
project: {
|
},
|
||||||
id: project.id
|
project: {
|
||||||
},
|
id: project.id
|
||||||
reporter: {
|
},
|
||||||
id: pickRandom(users)
|
reporter: {
|
||||||
}
|
id: pickRandom(users)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (issueType.subtask) {
|
|
||||||
data = {
|
|
||||||
parent: {
|
|
||||||
key: parentIssue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(data)
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (issueType.subtask) {
|
||||||
|
data = {
|
||||||
|
parent: {
|
||||||
|
key: parentIssue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
![jira-10050-field-description](adf-media://79411c6b-50e0-477f-b4ed-ac3a5887750c)
|
![jira-10050-field-description](adf-media://79411c6b-50e0-477f-b4ed-ac3a5887750c)
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,25 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "orderedList",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "listItem",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "paragraph",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"text": "Another list"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,9 @@
|
||||||
9. Number list item 9
|
9. Number list item 9
|
||||||
|
|
||||||
10. Number list item 10
|
10. Number list item 10
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
1. Another list
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||||
import Vuex from 'vuex';
|
import Vuex from 'vuex';
|
||||||
import { createStore } from '~/mr_notes/stores';
|
import { createStore } from '~/mr_notes/stores';
|
||||||
import NoChanges from '~/diffs/components/no_changes.vue';
|
import NoChanges from '~/diffs/components/no_changes.vue';
|
||||||
|
import { GlButton } from '@gitlab/ui';
|
||||||
|
|
||||||
describe('Diff no changes empty state', () => {
|
describe('Diff no changes empty state', () => {
|
||||||
let vm;
|
let vm;
|
||||||
|
@ -37,4 +38,11 @@ describe('Diff no changes empty state', () => {
|
||||||
|
|
||||||
expect(vm.contains('script')).toBe(false);
|
expect(vm.contains('script')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Renders', () => {
|
||||||
|
it('Show create commit button', () => {
|
||||||
|
createComponent();
|
||||||
|
expect(vm.find(GlButton).exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -235,4 +235,25 @@ RSpec.describe IconsHelper do
|
||||||
.to eq("<span class=\"gl-snippet-icon gl-snippet-icon-download\"></span>")
|
.to eq("<span class=\"gl-snippet-icon gl-snippet-icon-download\"></span>")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'loading_icon' do
|
||||||
|
it 'returns span with gl-spinner class and default configuration' do
|
||||||
|
expect(loading_icon.to_s)
|
||||||
|
.to eq '<span class="gl-spinner gl-spinner-orange gl-spinner-sm" aria-label="Loading"></span>'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when css_class is provided' do
|
||||||
|
it 'appends css_class to gl-spinner element' do
|
||||||
|
expect(loading_icon(css_class: 'gl-mr-2').to_s)
|
||||||
|
.to eq '<span class="gl-spinner gl-spinner-orange gl-spinner-sm gl-mr-2" aria-label="Loading"></span>'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when container is true' do
|
||||||
|
it 'creates a container that has the gl-spinner-container class selector' do
|
||||||
|
expect(loading_icon(container: true).to_s)
|
||||||
|
.to eq '<div class="gl-spinner-container"><span class="gl-spinner gl-spinner-orange gl-spinner-sm" aria-label="Loading"></span></div>'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -235,6 +235,14 @@ RSpec.describe AlertManagement::Alert do
|
||||||
|
|
||||||
it { is_expected.to contain_exactly(acknowledged_alert, triggered_alert) }
|
it { is_expected.to contain_exactly(acknowledged_alert, triggered_alert) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.not_resolved' do
|
||||||
|
subject { described_class.not_resolved }
|
||||||
|
|
||||||
|
let!(:acknowledged_alert) { create(:alert_management_alert, :acknowledged, project: project) }
|
||||||
|
|
||||||
|
it { is_expected.to contain_exactly(acknowledged_alert, triggered_alert, ignored_alert) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.last_prometheus_alert_by_project_id' do
|
describe '.last_prometheus_alert_by_project_id' do
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe GroupVariableEntity do
|
RSpec.describe Ci::GroupVariableEntity do
|
||||||
let(:variable) { create(:ci_group_variable) }
|
let(:variable) { create(:ci_group_variable) }
|
||||||
let(:entity) { described_class.new(variable) }
|
let(:entity) { described_class.new(variable) }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe VariableEntity do
|
RSpec.describe Ci::VariableEntity do
|
||||||
let(:variable) { create(:ci_variable) }
|
let(:variable) { create(:ci_variable) }
|
||||||
let(:entity) { described_class.new(variable) }
|
let(:entity) { described_class.new(variable) }
|
||||||
|
|
|
@ -39,22 +39,27 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
|
||||||
|
|
||||||
context 'when Prometheus alert status is firing' do
|
context 'when Prometheus alert status is firing' do
|
||||||
context 'when alert with the same fingerprint already exists' do
|
context 'when alert with the same fingerprint already exists' do
|
||||||
let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
|
let!(:alert) { create(:alert_management_alert, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
|
||||||
|
|
||||||
it 'increases alert events count' do
|
it_behaves_like 'adds an alert management alert event'
|
||||||
expect { execute }.to change { alert.reload.events }.by(1)
|
|
||||||
|
context 'existing alert is resolved' do
|
||||||
|
let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
|
||||||
|
|
||||||
|
it_behaves_like 'creates an alert management alert'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when status can be changed' do
|
context 'existing alert is ignored' do
|
||||||
it 'changes status to triggered' do
|
let!(:alert) { create(:alert_management_alert, :ignored, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
|
||||||
expect { execute }.to change { alert.reload.triggered? }.to(true)
|
|
||||||
end
|
it_behaves_like 'adds an alert management alert event'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not executes the alert service hooks' do
|
context 'two existing alerts, one resolved one open' do
|
||||||
expect(alert).not_to receive(:execute_services)
|
let!(:resolved_alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
|
||||||
|
let!(:alert) { create(:alert_management_alert, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
|
||||||
|
|
||||||
subject
|
it_behaves_like 'adds an alert management alert event'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when status change did not succeed' do
|
context 'when status change did not succeed' do
|
||||||
|
@ -73,23 +78,11 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
|
||||||
execute
|
execute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it { is_expected.to be_success }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when alert does not exist' do
|
context 'when alert does not exist' do
|
||||||
context 'when alert can be created' do
|
context 'when alert can be created' do
|
||||||
it 'creates a new alert' do
|
it_behaves_like 'creates an alert management alert'
|
||||||
expect { execute }.to change { AlertManagement::Alert.where(project: project).count }.by(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'executes the alert service hooks' do
|
|
||||||
slack_service = create(:service, type: 'SlackService', project: project, alert_events: true, active: true)
|
|
||||||
|
|
||||||
subject
|
|
||||||
|
|
||||||
expect(ProjectServiceWorker).to have_received(:perform_async).with(slack_service.id, an_instance_of(Hash))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when alert cannot be created' do
|
context 'when alert cannot be created' do
|
||||||
|
|
|
@ -64,12 +64,6 @@ RSpec.describe Projects::Alerting::NotifyService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'NotifyService does not create alert' do
|
|
||||||
it 'does not create alert' do
|
|
||||||
expect { subject }.not_to change(AlertManagement::Alert, :count)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
let(:token) { 'invalid-token' }
|
let(:token) { 'invalid-token' }
|
||||||
let(:starts_at) { Time.current.change(usec: 0) }
|
let(:starts_at) { Time.current.change(usec: 0) }
|
||||||
|
@ -107,62 +101,64 @@ RSpec.describe Projects::Alerting::NotifyService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with valid payload' do
|
context 'with valid payload' do
|
||||||
|
shared_examples 'assigns the alert properties' do
|
||||||
|
it 'ensure that created alert has all data properly assigned' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(last_alert_attributes).to match(
|
||||||
|
project_id: project.id,
|
||||||
|
title: payload_raw.fetch(:title),
|
||||||
|
started_at: Time.zone.parse(payload_raw.fetch(:start_time)),
|
||||||
|
severity: payload_raw.fetch(:severity),
|
||||||
|
status: AlertManagement::Alert::STATUSES[:triggered],
|
||||||
|
events: 1,
|
||||||
|
hosts: payload_raw.fetch(:hosts),
|
||||||
|
payload: payload_raw.with_indifferent_access,
|
||||||
|
issue_id: nil,
|
||||||
|
description: payload_raw.fetch(:description),
|
||||||
|
monitoring_tool: payload_raw.fetch(:monitoring_tool),
|
||||||
|
service: payload_raw.fetch(:service),
|
||||||
|
fingerprint: Digest::SHA1.hexdigest(fingerprint),
|
||||||
|
ended_at: nil,
|
||||||
|
prometheus_alert_id: nil,
|
||||||
|
environment_id: nil
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
let(:last_alert_attributes) do
|
let(:last_alert_attributes) do
|
||||||
AlertManagement::Alert.last.attributes
|
AlertManagement::Alert.last.attributes
|
||||||
.except('id', 'iid', 'created_at', 'updated_at')
|
.except('id', 'iid', 'created_at', 'updated_at')
|
||||||
.with_indifferent_access
|
.with_indifferent_access
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates AlertManagement::Alert' do
|
it_behaves_like 'creates an alert management alert'
|
||||||
expect { subject }.to change(AlertManagement::Alert, :count).by(1)
|
it_behaves_like 'assigns the alert properties'
|
||||||
end
|
|
||||||
|
|
||||||
it 'created alert has all data properly assigned' do
|
|
||||||
subject
|
|
||||||
|
|
||||||
expect(last_alert_attributes).to match(
|
|
||||||
project_id: project.id,
|
|
||||||
title: payload_raw.fetch(:title),
|
|
||||||
started_at: Time.zone.parse(payload_raw.fetch(:start_time)),
|
|
||||||
severity: payload_raw.fetch(:severity),
|
|
||||||
status: AlertManagement::Alert::STATUSES[:triggered],
|
|
||||||
events: 1,
|
|
||||||
hosts: payload_raw.fetch(:hosts),
|
|
||||||
payload: payload_raw.with_indifferent_access,
|
|
||||||
issue_id: nil,
|
|
||||||
description: payload_raw.fetch(:description),
|
|
||||||
monitoring_tool: payload_raw.fetch(:monitoring_tool),
|
|
||||||
service: payload_raw.fetch(:service),
|
|
||||||
fingerprint: Digest::SHA1.hexdigest(fingerprint),
|
|
||||||
ended_at: nil,
|
|
||||||
prometheus_alert_id: nil,
|
|
||||||
environment_id: nil
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'executes the alert service hooks' do
|
|
||||||
slack_service = create(:service, type: 'SlackService', project: project, alert_events: true, active: true)
|
|
||||||
subject
|
|
||||||
|
|
||||||
expect(ProjectServiceWorker).to have_received(:perform_async).with(slack_service.id, an_instance_of(Hash))
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'existing alert with same fingerprint' do
|
context 'existing alert with same fingerprint' do
|
||||||
let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
|
let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
|
||||||
let!(:existing_alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
|
let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
|
||||||
|
|
||||||
it 'does not create AlertManagement::Alert' do
|
it_behaves_like 'adds an alert management alert event'
|
||||||
expect { subject }.not_to change(AlertManagement::Alert, :count)
|
|
||||||
|
context 'existing alert is resolved' do
|
||||||
|
let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint_sha) }
|
||||||
|
|
||||||
|
it_behaves_like 'creates an alert management alert'
|
||||||
|
it_behaves_like 'assigns the alert properties'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'increments the existing alert count' do
|
context 'existing alert is ignored' do
|
||||||
expect { subject }.to change { existing_alert.reload.events }.from(1).to(2)
|
let!(:alert) { create(:alert_management_alert, :ignored, project: project, fingerprint: fingerprint_sha) }
|
||||||
|
|
||||||
|
it_behaves_like 'adds an alert management alert event'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not executes the alert service hooks' do
|
context 'two existing alerts, one resolved one open' do
|
||||||
subject
|
let!(:resolved_existing_alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint_sha) }
|
||||||
|
let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
|
||||||
|
|
||||||
expect(ProjectServiceWorker).not_to have_received(:perform_async)
|
it_behaves_like 'adds an alert management alert event'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -174,9 +170,7 @@ RSpec.describe Projects::Alerting::NotifyService do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates AlertManagement::Alert' do
|
it_behaves_like 'creates an alert management alert'
|
||||||
expect { subject }.to change(AlertManagement::Alert, :count).by(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'created alert has all data properly assigned' do
|
it 'created alert has all data properly assigned' do
|
||||||
subject
|
subject
|
||||||
|
@ -218,19 +212,19 @@ RSpec.describe Projects::Alerting::NotifyService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'does not process incident issues due to error', http_status: :bad_request
|
it_behaves_like 'does not process incident issues due to error', http_status: :bad_request
|
||||||
it_behaves_like 'NotifyService does not create alert'
|
it_behaves_like 'does not an create alert management alert'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when alert already exists' do
|
context 'when alert already exists' do
|
||||||
let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
|
let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
|
||||||
let!(:existing_alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
|
let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
|
||||||
|
|
||||||
context 'when existing alert does not have an associated issue' do
|
context 'when existing alert does not have an associated issue' do
|
||||||
it_behaves_like 'processes incident issues'
|
it_behaves_like 'processes incident issues'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when existing alert has an associated issue' do
|
context 'when existing alert has an associated issue' do
|
||||||
let!(:existing_alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: fingerprint_sha) }
|
let!(:alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: fingerprint_sha) }
|
||||||
|
|
||||||
it_behaves_like 'does not process incident issues'
|
it_behaves_like 'does not process incident issues'
|
||||||
end
|
end
|
||||||
|
@ -246,14 +240,14 @@ RSpec.describe Projects::Alerting::NotifyService do
|
||||||
|
|
||||||
context 'with invalid token' do
|
context 'with invalid token' do
|
||||||
it_behaves_like 'does not process incident issues due to error', http_status: :unauthorized
|
it_behaves_like 'does not process incident issues due to error', http_status: :unauthorized
|
||||||
it_behaves_like 'NotifyService does not create alert'
|
it_behaves_like 'does not an create alert management alert'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with deactivated Alerts Service' do
|
context 'with deactivated Alerts Service' do
|
||||||
let!(:alerts_service) { create(:alerts_service, :inactive, project: project) }
|
let!(:alerts_service) { create(:alerts_service, :inactive, project: project) }
|
||||||
|
|
||||||
it_behaves_like 'does not process incident issues due to error', http_status: :forbidden
|
it_behaves_like 'does not process incident issues due to error', http_status: :forbidden
|
||||||
it_behaves_like 'NotifyService does not create alert'
|
it_behaves_like 'does not an create alert management alert'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
RSpec.shared_examples 'creates an alert management alert' do
|
||||||
|
it { is_expected.to be_success }
|
||||||
|
|
||||||
|
it 'creates AlertManagement::Alert' do
|
||||||
|
expect { subject }.to change(AlertManagement::Alert, :count).by(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'executes the alert service hooks' do
|
||||||
|
slack_service = create(:service, type: 'SlackService', project: project, alert_events: true, active: true)
|
||||||
|
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(ProjectServiceWorker).to have_received(:perform_async).with(slack_service.id, an_instance_of(Hash))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.shared_examples 'does not an create alert management alert' do
|
||||||
|
it 'does not create alert' do
|
||||||
|
expect { subject }.not_to change(AlertManagement::Alert, :count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.shared_examples 'adds an alert management alert event' do
|
||||||
|
it { is_expected.to be_success }
|
||||||
|
|
||||||
|
it 'does not create an alert' do
|
||||||
|
expect { subject }.not_to change(AlertManagement::Alert, :count)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'increases alert events count' do
|
||||||
|
expect { subject }.to change { alert.reload.events }.by(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not executes the alert service hooks' do
|
||||||
|
expect(alert).not_to receive(:execute_services)
|
||||||
|
|
||||||
|
subject
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue