Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-07-13 21:09:24 +00:00
parent d9aac35d79
commit 0698388e65
60 changed files with 596 additions and 219 deletions

View File

@ -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>

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) }

View File

@ -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

View File

@ -0,0 +1,6 @@
# frozen_string_literal: true
module Ci
class GroupVariableEntity < Ci::BasicVariableEntity
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
module Ci
class GroupVariableSerializer < BaseSerializer
entity ::Ci::GroupVariableEntity
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
module Ci
class VariableEntity < Ci::BasicVariableEntity
expose :environment_scope
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
module Ci
class VariableSerializer < BaseSerializer
entity ::Ci::VariableEntity
end
end

View File

@ -1,4 +0,0 @@
# frozen_string_literal: true
class GroupVariableEntity < Ci::BasicVariableEntity
end

View File

@ -1,5 +0,0 @@
# frozen_string_literal: true
class GroupVariableSerializer < BaseSerializer
entity GroupVariableEntity
end

View File

@ -1,5 +0,0 @@
# frozen_string_literal: true
class VariableEntity < Ci::BasicVariableEntity
expose :environment_scope
end

View File

@ -1,5 +0,0 @@
# frozen_string_literal: true
class VariableSerializer < BaseSerializer
entity VariableEntity
end

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
---
title: Support fenced code blocks in Atlassian Document Format converter
merge_request: 35065
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Open new alert when existing alert is resolved
merge_request: 36261
author:
type: added

View File

@ -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

View File

@ -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

View File

@ -21,6 +21,7 @@ exceptions:
- CLI - CLI
- CNAME - CNAME
- CPU - CPU
- CORE
- CSS - CSS
- CSV - CSV
- DNS - DNS

View File

@ -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."

View File

@ -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` |

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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.

View File

@ -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:**

View File

@ -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)

View File

@ -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

View File

@ -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]

View File

@ -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 ""

View File

@ -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

View File

@ -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

View File

@ -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"
}
]
}
]
}
]
} }
] ]
} }

View File

@ -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
```

View File

@ -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)

View File

@ -146,6 +146,25 @@
] ]
} }
] ]
},
{
"type": "orderedList",
"content": [
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Another list"
}
]
}
]
}
]
} }
] ]
} }

View File

@ -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
<!-- -->

View File

@ -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);
});
});
}); });

View File

@ -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

View File

@ -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

View File

@ -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) }

View File

@ -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) }

View File

@ -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

View File

@ -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

View File

@ -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