Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-22 12:08:59 +00:00
parent 44c4a8ee1e
commit 421f6c92d5
79 changed files with 1715 additions and 1338 deletions

View File

@ -60,7 +60,7 @@ workflow:
variables:
PG_VERSION: "12"
DEFAULT_CI_IMAGE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}.patched-golang-1.17-node-16.14-postgresql-${PG_VERSION}:git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-yarn-1.22-graphicsmagick-1.3.36"
DEFAULT_CI_IMAGE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}.patched-golang-1.17-node-16.14-postgresql-${PG_VERSION}:rubygems-3.2-git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-yarn-1.22-graphicsmagick-1.3.36"
RAILS_ENV: "test"
NODE_ENV: "test"
BUNDLE_WITHOUT: "production:development"

View File

@ -11,7 +11,7 @@
- .default-retry
- .default-before_script
- .assets-compile-cache
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}-git-2.33-lfs-2.9-node-16.14-yarn-1.22-graphicsmagick-1.3.36
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}-node-16.14:rubygems-3.2-git-2.33-lfs-2.9-yarn-1.22-graphicsmagick-1.3.36
variables:
SETUP_DB: "false"
WEBPACK_VENDOR_DLL: "true"

View File

@ -436,6 +436,33 @@
"type": "string"
}
},
"pull_policy": {
"markdownDescription": "Specifies how to pull the image in Runner. It can be one of `always`, `never` or `if-not-present`. The default value is `always`. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#servicepull_policy).",
"default": "always",
"oneOf": [
{
"type": "string",
"enum": [
"always",
"never",
"if-not-present"
]
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"always",
"never",
"if-not-present"
]
},
"minItems": 1,
"uniqueItems": true
}
]
},
"command": {
"type": "array",
"description": "Command or script that should be used as the container's command. It will be translated to arguments passed to Docker after the image's name. The syntax is similar to Dockerfile's CMD directive, where each shell token is a separate string in the array.",

View File

@ -14,7 +14,6 @@ module Projects
respond_to :json, only: [:reset_alerting_token, :reset_pagerduty_token]
helper_method :error_tracking_setting
helper_method :tracing_setting
feature_category :incident_management
urgency :low
@ -60,19 +59,9 @@ module Projects
::Gitlab::Tracking::IncidentManagement.track_from_params(
update_params[:incident_management_setting_attributes]
)
track_tracing_external_url
end
end
def track_tracing_external_url
external_url_previous_change = project&.tracing_setting&.external_url_previous_change
return unless external_url_previous_change
return unless external_url_previous_change[0].blank? && external_url_previous_change[1].present?
::Gitlab::Tracking.event('project:operations:tracing', 'external_url_populated', user: current_user, project: project, namespace: project.namespace)
end
def alerting_params
{ alerting_setting_attributes: { regenerate_token: true } }
end
@ -124,10 +113,6 @@ module Projects
project.build_error_tracking_setting
end
def tracing_setting
@tracing_setting ||= project.tracing_setting || project.build_tracing_setting
end
def update_params
params.require(:project).permit(permitted_project_params)
end
@ -147,8 +132,7 @@ module Projects
project: [:slug, :name, :organization_slug, :organization_name]
],
grafana_integration_attributes: [:token, :grafana_url, :enabled],
tracing_setting_attributes: [:external_url]
grafana_integration_attributes: [:token, :grafana_url, :enabled]
}
end
end

View File

@ -38,7 +38,7 @@ module AlertManagement
if alert.resolve(incoming_payload.ends_at)
SystemNoteService.change_alert_status(alert, User.alert_bot)
close_issue(alert.issue) if auto_close_incident?
close_issue(alert.issue_id) if auto_close_incident?
else
logger.warn(
message: 'Unable to update AlertManagement::Alert status to resolved',
@ -52,14 +52,10 @@ module AlertManagement
alert.register_new_event!
end
def close_issue(issue)
return if issue.blank? || issue.closed?
def close_issue(issue_id)
return unless issue_id
::Issues::CloseService
.new(project: project, current_user: User.alert_bot)
.execute(issue, system_note: false)
SystemNoteService.auto_resolve_prometheus_alert(issue, project, User.alert_bot) if issue.reset.closed?
::IncidentManagement::CloseIncidentWorker.perform_async(issue_id)
end
def process_new_alert
@ -78,7 +74,7 @@ module AlertManagement
end
def process_incident_issues
return if alert.issue || alert.resolved?
return if alert.issue_id || alert.resolved?
::IncidentManagement::ProcessAlertWorkerV2.perform_async(alert.id)
end

View File

@ -27,3 +27,5 @@
= link_to _('Learn more.'), help_page_path('user/admin_area/review_abuse_reports.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'abuse'
= render_if_exists 'admin/application_settings/git_abuse_rate_limit'

View File

@ -14,15 +14,3 @@
s_('ClusterIntegration|Enable Prometheus integration'),
help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link }
= prometheus_form.submit _('Save changes'), class: 'btn gl-button btn-confirm'
- if Feature.enabled?(:monitor_logging, @project)
.sub-section.form-group
= gitlab_ui_form_for @elastic_stack_integration, as: :integration, namespace: :elastic_stack, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |elastic_stack_form|
= elastic_stack_form.hidden_field :application_type
.form-group.gl-form-group
- help_text = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Elasticsearch for pod logs.')
- help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations", anchor: "elastic-stack-cluster-integration"), target: '_blank', rel: 'noopener noreferrer')
= elastic_stack_form.gitlab_ui_checkbox_component :enabled,
s_('ClusterIntegration|Enable Elastic Stack integration'),
help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link }
= elastic_stack_form.submit _('Save changes'), class: 'btn gl-button btn-confirm'

View File

@ -1,5 +1,5 @@
- managed_namespace_help_text = s_('ClusterIntegration|Set a prefix for your namespaces. If not set, defaults to your project path. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
- non_managed_namespace_help_text = s_('ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals.')
- non_managed_namespace_help_text = s_('ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, and Web terminals.')
- managed_namespace_help_link = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank', rel: 'noopener noreferrer'
.js-namespace-prefixed

View File

@ -39,7 +39,7 @@
%p
= _('Public projects are an easy way to allow everyone to have read-only access.')
= link_to "https://docs.gitlab.com/", class: link_classes do
= link_to Gitlab::Saas::doc_url, class: link_classes do
.blank-state-icon
= custom_icon("lightbulb", size: 50)
.blank-state-body.gl-sm-pl-0.gl-pl-6

View File

@ -1,24 +0,0 @@
- setting = tracing_setting
%section.settings.border-0.no-animate
.settings-header{ :class => 'border-top' }
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Tracing')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= _('Expand')
%p
= _('Embed an image of your existing Jaeger server in GitLab.')
= link_to _('Learn more.'), help_page_path('operations/tracing'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= form_for @project, url: project_settings_operations_path(@project), method: :patch do |f|
= form_errors(@project)
.form-group
= f.fields_for :tracing_setting_attributes, setting do |form|
= form.label :external_url, _('Jaeger URL'), class: 'label-bold'
= form.url_field :external_url, class: 'form-control gl-form-input', placeholder: 'https://jaeger.example.com'
%p.form-text.text-muted
- jaeger_help_url = 'https://www.jaegertracing.io/docs/getting-started/'
- link_start_tag = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: jaeger_help_url }
- link_end_tag = "#{sprite_icon('external-link', css_class: 'gl-ml-2 gl-vertical-align-middle')}</a>".html_safe
= _('Learn more about %{link_start_tag}Jaeger configuration%{link_end_tag}.').html_safe % { link_start_tag: link_start_tag, link_end_tag: link_end_tag }
= f.submit _('Save changes'), class: 'gl-button btn btn-confirm'

View File

@ -20,7 +20,6 @@
= html_escape(s_('Deprecations|For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}.')) % {opstrace_link_start: opstrace_link_start, link_end: link_end }
= render 'projects/settings/operations/metrics_dashboard'
= render 'projects/settings/operations/tracing' if Feature.enabled?(:monitor_tracing, @project)
= render 'projects/settings/operations/error_tracking'
= render 'projects/settings/operations/alert_management'
= render 'projects/settings/operations/incidents'

View File

@ -2389,6 +2389,15 @@
:weight: 2
:idempotent: true
:tags: []
- :name: incident_management_close_incident
:worker_name: IncidentManagement::CloseIncidentWorker
:feature_category: :incident_management
:has_external_dependencies: true
:urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent: true
:tags: []
- :name: integrations_create_external_cross_reference
:worker_name: Integrations::CreateExternalCrossReferenceWorker
:feature_category: :integrations

View File

@ -0,0 +1,43 @@
# frozen_string_literal: true
module IncidentManagement
class CloseIncidentWorker
include ApplicationWorker
idempotent!
deduplicate :until_executed
data_consistency :always
feature_category :incident_management
urgency :low
# Issues:CloseService execute webhooks which are treated as external dependencies
worker_has_external_dependencies!
def perform(issue_id)
incident = Issue.incident.opened.find_by_id(issue_id)
return unless incident
close_incident(incident)
add_system_note(incident)
end
private
def user
@user ||= User.alert_bot
end
def close_incident(incident)
::Issues::CloseService
.new(project: incident.project, current_user: user)
.execute(incident, system_note: false)
end
def add_system_note(incident)
return unless incident.reset.closed?
SystemNoteService.auto_resolve_prometheus_alert(incident, incident.project, user)
end
end
end

View File

@ -0,0 +1,8 @@
---
name: git_abuse_rate_limit_feature_flag
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87872
rollout_issue_url:
milestone: '15.1'
type: development
group: group::anti-abuse
default_enabled: false

View File

@ -2,15 +2,22 @@
require 'wikicloth'
require 'wikicloth/wiki_buffer/var'
require 'digest/sha2'
# Adds patch for changes in this PR: https://github.com/nricciar/wikicloth/pull/112/files
# Adds patch for changes in these PRs:
#
# That fix has already been merged, but the maintainers are not releasing new versions, so we
# need to patch it here.
# https://github.com/nricciar/wikicloth/pull/112
# https://github.com/nricciar/wikicloth/pull/131
#
# The first fix has already been merged, but the second has not,
# and the maintainers are not releasing new versions, so we
# need to patch them here.
#
# If they ever do release a version, then we can remove this file.
#
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/334056#note_745336618
# See:
# - https://gitlab.com/gitlab-org/gitlab/-/issues/334056#note_745336618
# - https://gitlab.com/gitlab-org/gitlab/-/issues/361266
# Guard to ensure we remember to delete this patch if they ever release a new version of wikicloth
raise 'New version of WikiCloth detected, please remove this patch' unless Gem::Version.new(WikiCloth::VERSION) == Gem::Version.new('0.8.1')
@ -30,9 +37,12 @@ raise 'New version of WikiCloth detected, please remove this patch' unless Gem::
# rubocop:disable Layout/EmptyLineAfterGuardClause
# rubocop:disable Performance/ReverseEach
# rubocop:disable Style/BlockDelimiters
# rubocop:disable Cop/LineBreakAroundConditionalBlock
# rubocop:disable Layout/MultilineBlockLayout
# rubocop:disable Layout/BlockEndNewline
# rubocop:disable Style/PerlBackrefs
# rubocop:disable Style/RegexpLiteralMixedPreserve
# rubocop:disable Style/RedundantRegexpCharacterClass
# rubocop:disable Performance/StringInclude
module WikiCloth
class WikiCloth
def render(opt={})
@ -110,7 +120,7 @@ module WikiCloth
key = params[0].to_s.strip
key_options = params[1..].collect { |p| p.is_a?(Hash) ? { :name => p[:name].strip, :value => p[:value].strip } : p.strip }
key_options ||= []
key_digest = Digest::MD5.hexdigest(key_options.to_a.sort {|x,y| (x.is_a?(Hash) ? x[:name] : x) <=> (y.is_a?(Hash) ? y[:name] : y) }.inspect)
key_digest = Digest::SHA256.hexdigest(key_options.to_a.sort {|x,y| (x.is_a?(Hash) ? x[:name] : x) <=> (y.is_a?(Hash) ? y[:name] : y) }.inspect)
return @options[:params][key] if @options[:params].has_key?(key)
# if we have a valid cache fragment use it
@ -138,6 +148,54 @@ module WikiCloth
end
end
end
class WikiBuffer::HTMLElement < WikiBuffer
def to_html
if NO_NEED_TO_CLOSE.include?(self.element_name)
return "<#{self.element_name} />" if SHORT_TAGS.include?(self.element_name)
return "</#{self.element_name}><#{self.element_name}>" if @tag_check == self.element_name
end
if ESCAPED_TAGS.include?(self.element_name)
# remove empty first line
self.element_content = $1 if self.element_content =~ /^\s*\n(.*)$/m
# escape all html inside this element
self.element_content = self.element_content.gsub('<','&lt;').gsub('>','&gt;')
# hack to fix <code><nowiki> nested mess
self.element_content = self.element_content.gsub(/&lt;[\/]*\s*nowiki\s*&gt;/,'')
end
case self.element_name
when "template"
@options[:link_handler].cache({ :name => self.element_attributes["__name"], :content => self.element_content, :sha256 => self.element_attributes["__hash"] })
return self.element_content
when "noinclude"
return self.in_template? ? "" : self.element_content
when "includeonly"
return self.in_template? ? self.element_content : ""
when "nowiki"
return self.element_content
when "a"
if self.element_attributes['href'] =~ /:\/\//
return @options[:link_handler].external_link(self.element_attributes['href'], self.element_content)
elsif self.element_attributes['href'].nil? || self.element_attributes['href'] =~ /^\s*([\?\/])/
# if a element has no href attribute, or href starts with / or ?
return elem.tag!(self.element_name, self.element_attributes) { |x| x << self.element_content }
end
else
if Extension.element_exists?(self.element_name)
return Extension.html_elements[self.element_name][:klass].new(@options).instance_exec( self, &Extension.html_elements[self.element_name][:block] ).to_s
end
end
tmp = elem.tag!(self.element_name, self.element_attributes) { |x| x << self.element_content }
unless ALLOWED_ELEMENTS.include?(self.element_name)
tmp.gsub!(/[\-!\|&"\{\}\[\]]/) { |r| self.escape_char(r) }
return tmp.gsub('<', '&lt;').gsub('>', '&gt;')
end
tmp
end
end
end
# rubocop:enable Style/ClassAndModuleChildren
# rubocop:enable Layout/SpaceAroundEqualsInParameterDefault
@ -154,6 +212,9 @@ end
# rubocop:enable Layout/EmptyLineAfterGuardClause
# rubocop:enable Performance/ReverseEach
# rubocop:enable Style/BlockDelimiters
# rubocop:enable Cop/LineBreakAroundConditionalBlock
# rubocop:enable Layout/MultilineBlockLayout
# rubocop:enable Layout/BlockEndNewline
# rubocop:enable Style/PerlBackrefs
# rubocop:enable Style/RegexpLiteralMixedPreserve
# rubocop:enable Style/RedundantRegexpCharacterClass
# rubocop:enable Performance/StringInclude

View File

@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: tracing
value_type: number
status: active
status: removed
time_frame: 28d
data_source: database
distribution:
@ -19,3 +19,5 @@ tier:
- ultimate
performance_indicator_type: []
milestone: "<13.9"
milestone_removed: "15.2"
removed_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90607"

View File

@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: tracing
value_type: number
status: active
status: removed
time_frame: all
data_source: database
distribution:
@ -19,3 +19,5 @@ tier:
- ultimate
performance_indicator_type: []
milestone: "<13.9"
milestone_removed: "15.2"
removed_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90607"

View File

@ -7,7 +7,7 @@ product_stage: monitor
product_group: group::monitor
product_category: tracing
value_type: number
status: active
status: removed
time_frame: all
data_source: database
distribution:
@ -18,3 +18,5 @@ tier:
- premium
- ultimate
milestone: "<13.9"
milestone_removed: "15.2"
removed_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90607"

View File

@ -221,6 +221,8 @@
- 2
- - incident_management_apply_incident_sla_exceeded_label
- 1
- - incident_management_close_incident
- 1
- - incident_management_oncall_rotations_persist_shifts_job
- 1
- - incident_management_pending_escalations_alert_check

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class AddMaxRepositoryDownloadsLimitToApplicationSettings < Gitlab::Database::Migration[2.0]
def change
add_column :application_settings, :max_number_of_repository_downloads,
:smallint,
default: 0,
null: false
add_column :application_settings, :max_number_of_repository_downloads_within_time_period,
:integer,
default: 0,
null: false
end
end

View File

@ -0,0 +1 @@
0bf44279d1fd78a8df1ec2898b6170e587fb2dd5d692b9c31648aa19dffa5fe8

View File

@ -11321,6 +11321,8 @@ CREATE TABLE application_settings (
container_registry_pre_import_tags_rate numeric(6,2) DEFAULT 0.5 NOT NULL,
license_usage_data_exported boolean DEFAULT false NOT NULL,
phone_verification_code_enabled boolean DEFAULT false NOT NULL,
max_number_of_repository_downloads smallint DEFAULT 0 NOT NULL,
max_number_of_repository_downloads_within_time_period integer DEFAULT 0 NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_container_registry_pre_import_tags_rate_positive CHECK ((container_registry_pre_import_tags_rate >= (0)::numeric)),
CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)),

View File

@ -12,7 +12,9 @@ type: howto
NOTE:
This is the final step in setting up a **secondary** Geo site. Stages of the
setup process must be completed in the documented order.
Before attempting the steps in this stage, [complete all prior stages](../setup/index.md#using-omnibus-gitlab).
If not, [complete all prior stages](../setup/index.md#using-omnibus-gitlab) before procceed.
Make sure you [set up the database replication](../setup/database.md), and [configured fast lookup of authorized SSH keys](../../operations/fast_ssh_key_lookup.md) in **both primary and secondary sites**.
The basic steps of configuring a **secondary** site are to:
@ -318,7 +320,7 @@ the **primary** site. After you sign in:
1. Verify that it's correctly identified as a **secondary** Geo site, and that
Geo is enabled.
The initial replication, or 'backfill', is probably still in progress. You
The initial replication may take some time. The status of the site or the backfill may still in progress. You
can monitor the synchronization process on each Geo site from the **primary**
site's **Geo Sites** dashboard in your browser.

View File

@ -17,8 +17,11 @@ PostgreSQL instances, the Omnibus roles cannot perform all necessary
configuration steps. In this case, use the [Geo with external PostgreSQL instances](external_database.md)
process instead.
NOTE:
The stages of the setup process must be completed in the documented order.
Before you attempt the steps in this stage, [complete all prior stages](../setup/index.md#using-omnibus-gitlab).
If not, [complete all prior stages](../setup/index.md#using-omnibus-gitlab) before proceeding.
Ensure the **secondary** site is running the same version of GitLab Enterprise Edition as the **primary** site. Confirm you have added the [premium or higher licenses](https://about.gitlab.com/pricing/) to your **primary** site.
Be sure to read and review all of these steps before you execute them in your
testing or production environments.

View File

@ -24,9 +24,10 @@ If you installed GitLab using the Omnibus packages (highly recommended):
1. [Set up the database replication](database.md) (`primary (read-write) <-> secondary (read-only)` topology).
1. [Configure fast lookup of authorized SSH keys in the database](../../operations/fast_ssh_key_lookup.md). This step is required and needs to be done on **both** the **primary** and **secondary** sites.
1. [Configure GitLab](../replication/configuration.md) to set the **primary** and **secondary** sites.
1. Optional: [Configure Object storage](../../object_storage.md)
1. Optional: [Configure a secondary LDAP server](../../auth/ldap/index.md) for the **secondary** sites. See [notes on LDAP](../index.md#ldap).
1. Optional: [Configure Geo secondary proxying](../secondary_proxy/index.md) to use a single, unified URL for all Geo sites. This step is recommended to accelerate most read requests while transparently proxying writes to the primary Geo site.
1. Follow the [Using a Geo Site](../replication/usage.md) guide.
1. [Configure Geo secondary proxying](../secondary_proxy/index.md) to use a single, unified URL for all Geo sites. This step is recommended to accelerate most read requests while transparently proxying writes to the primary Geo site.
## Post-installation documentation

View File

@ -379,6 +379,8 @@ listed in the descriptions of the relevant settings.
| `max_personal_access_token_lifetime` **(ULTIMATE SELF)** | integer | no | Maximum allowable lifetime for access tokens in days. |
| `max_ssh_key_lifetime` **(ULTIMATE SELF)** | integer | no | Maximum allowable lifetime for SSH keys in days. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1007) in GitLab 14.6. |
| `metrics_method_call_threshold` | integer | no | A method call is only tracked when it takes longer than the given amount of milliseconds. |
| `max_number_of_repository_downloads` **(ULTIMATE SELF)** | integer | no | Maximum number of unique repositories a user can download in the specified time period before they are banned. Default: 0, Maximum: 10,000 repositories. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87980) in GitLab 15.1. |
| `max_number_of_repository_downloads_within_time_period` **(ULTIMATE SELF)** | integer | no | Reporting time period (in seconds). Default: 0, Maximum: 864000 seconds (10 days). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87980) in GitLab 15.1. |
| `mirror_available` | boolean | no | Allow repository mirroring to configured by project Maintainers. If disabled, only Administrators can configure repository mirroring. |
| `mirror_capacity_threshold` **(PREMIUM)** | integer | no | Minimum capacity to be available before scheduling more mirrors preemptively. |
| `mirror_max_capacity` **(PREMIUM)** | integer | no | Maximum number of mirrors that can be synchronizing at the same time. |

View File

@ -28,7 +28,7 @@ The following table lists examples with step-by-step tutorials that are containe
| Deployment with Dpl | [Using `dpl` as deployment tool](deployment/index.md). |
| GitLab Pages | See the [GitLab Pages](../../user/project/pages/index.md) documentation for a complete example of deploying a static site. |
| End-to-end testing | [End-to-end testing with GitLab CI/CD and WebdriverIO](end_to_end_testing_webdriverio/index.md). |
| Load performance testing | [Load Performance Testing with the k6 container](../../user/project/merge_requests/load_performance_testing.md). |
| Load performance testing | [Load Performance Testing with the k6 container](../testing/load_performance_testing.md). |
| Multi project pipeline | [Build, test deploy using multi project pipeline](https://gitlab.com/gitlab-examples/upstream-project). |
| npm with semantic-release | [Publish npm packages to the GitLab Package Registry using semantic-release](semantic-release.md). |
| PHP with Laravel, Envoy | [Test and deploy Laravel applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md). |

View File

@ -84,7 +84,7 @@ GitLab CI/CD features, grouped by DevOps stage, include:
| [Connect to cloud services](cloud_services/index.md) | Connect to cloud providers using OpenID Connect (OIDC) to retrieve temporary credentials to access services or secrets. |
| **Verify** | |
| [Browser Performance Testing](testing/browser_performance_testing.md) | Quickly determine the browser performance impact of pending code changes. |
| [Load Performance Testing](../user/project/merge_requests/load_performance_testing.md) | Quickly determine the server performance impact of pending code changes. |
| [Load Performance Testing](testing/load_performance_testing.md) | Quickly determine the server performance impact of pending code changes. |
| [CI services](services/index.md) | Link Docker containers with your base image. |
| [GitLab CI/CD for external repositories](ci_cd_for_external_repos/index.md) | Get the benefits of GitLab CI/CD combined with repositories in GitHub and Bitbucket Cloud. |
| [Interactive Web Terminals](interactive_web_terminal/index.md) | Open an interactive web terminal to debug the running jobs. |

View File

@ -1,68 +1,11 @@
---
stage: Verify
group: Pipeline Insights
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/#assignments
redirect_to: 'testing/metrics_reports.md'
remove_date: '2022-08-31'
---
# Metrics Reports **(PREMIUM)**
This document was moved to [another location](testing/metrics_reports.md).
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9788) in GitLab 11.10. Requires GitLab Runner 11.10 and above.
GitLab provides a lot of great reporting tools for things like [merge requests](../user/project/merge_requests/index.md) - [Unit test reports](testing/unit_test_reports.md), [code quality](testing/code_quality.md), and performance tests. While JUnit is a great open framework for tests that "pass" or "fail", it is also important to see other types of metrics from a given change.
You can configure your job to use custom Metrics Reports, and GitLab displays a report on the merge request so that it's easier and faster to identify changes without having to check the entire log.
![Metrics Reports](img/metrics_reports_v13_0.png)
## Use cases
Consider the following examples of data that can use Metrics Reports:
1. Memory usage
1. Load testing results
1. Code complexity
1. Code coverage stats
## How it works
Metrics for a branch are read from the latest metrics report artifact (default filename: `metrics.txt`) as string values.
For an MR, the values of these metrics from the feature branch are compared to the values from the target branch. Then they are displayed in the MR widget in this order:
- Existing metrics with changed values.
- Metrics that have been added by the MR. Marked with a **New** badge.
- Metrics that have been removed by the MR. Marked with a **Removed** badge.
- Existing metrics with unchanged values.
## How to set it up
Add a job that creates a [metrics report](yaml/artifacts_reports.md#artifactsreportsmetrics) (default filename: `metrics.txt`). The file should conform to the [OpenMetrics](https://openmetrics.io/) format.
For example:
```yaml
metrics:
script:
- echo 'metric_name metric_value' > metrics.txt
artifacts:
reports:
metrics: metrics.txt
```
## Advanced Example
An advanced example of an OpenMetrics text file (from the [Prometheus documentation](https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md#text-format-example))
renders in the merge request widget as:
![Metrics Reports Advanced](img/metrics_reports_advanced_v13_0.png)
## Troubleshooting
### Metrics reports did not change
You can see `Metrics reports did not change` when trying to view metrics reports in merge requests. Reasons for this are:
- The target branch for the merge request doesn't have a baseline metrics report for comparison.
- You don't have GitLab license at the Premium tier or above.
There is [an issue open](https://gitlab.com/gitlab-org/gitlab/-/issues/343065) to improve this message.
<!-- This redirect file can be deleted after <2022-09-22>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -7,22 +7,33 @@ type: reference
# CI/CD minutes quota **(PREMIUM)**
[Shared runners](../runners/runners_scope.md#shared-runners) are shared with every project and group in a GitLab instance.
When jobs run on shared runners, CI/CD minutes are used.
Administrators can limit the amount of time that projects can use to run jobs on
[shared runners](../runners/runners_scope.md#shared-runners) each month. This limit
is tracked with a quota of CI/CD minutes.
You can set limits on the number of CI/CD minutes that are used each month.
By default, one minute of execution time by a single job uses
one CI/CD minute. The total amount of CI/CD minutes used by a pipeline is
[the sum of all its jobs' durations](#how-cicd-minute-usage-is-calculated).
Jobs can run concurrently, so the total CI/CD minute usage can be higher than the
end-to-end duration of a pipeline.
- On GitLab.com, the quota of CI/CD minutes is set for each [namespace](../../user/group/index.md#namespaces),
and is determined by [your license tier](https://about.gitlab.com/pricing/).
- On self-managed GitLab instances, the quota of CI/CD minutes for each namespace is set by administrators.
On GitLab.com:
In addition to the monthly quota, you can add more CI/CD minutes when needed.
- CI/CD minutes quotas are enabled for both public and private projects, but public
projects [consume CI/CD minutes at a slower rate](#cost-factor).
- The base monthly CI/CD minutes quota for a GitLab.com [namespace](../../user/group/index.md#namespaces)
is determined by its [license tier](https://about.gitlab.com/pricing/).
- You can [purchase additional CI/CD minutes](#purchase-additional-cicd-minutes)
if you need more than the number of CI/CD minutes in your monthly quota.
- On GitLab.com, you can [purchase additional CI/CD minutes](#purchase-additional-cicd-minutes).
- On self-managed GitLab instances, administrators can [assign more CI/CD minutes](#set-the-quota-of-cicd-minutes-for-a-specific-namespace).
On self-managed GitLab instances:
[Specific runners](../runners/runners_scope.md#specific-runners)
are not subject to a quota of CI/CD minutes.
- CI/CD minutes quotas are disabled by default.
- When enabled, CI/CD minutes quotas apply to private projects only.
- Administrators can [assign more CI/CD minutes](#set-the-quota-of-cicd-minutes-for-a-specific-namespace)
if a namespace uses all the CI/CD minutes in its monthly quota.
[Specific runners](../runners/runners_scope.md#specific-runners) are not subject to a quota of CI/CD minutes.
## Set the quota of CI/CD minutes for all namespaces
@ -160,47 +171,44 @@ To purchase additional minutes for your personal namespace:
After your payment is processed, the additional CI/CD minutes are added to your personal
namespace.
## How CI/CD minutes are calculated
## How CI/CD minute usage is calculated
CI/CD minutes for individual jobs are calculated based on:
- The duration the job runs.
- The visibility of the projects where the job runs.
GitLab uses this formula to calculate CI/CD minutes consumed by a job:
GitLab uses this formula to calculate the CI/CD minute usage of a job:
```plaintext
Job duration * Cost factor
```
- **Job duration**: The time, in seconds, that a job took to run on a shared runner.
It does not include time spent in `created` or `pending` status.
- **Cost factor**: A number based on project visibility.
- **Job duration**: The time, in seconds, that a job took to run on a shared runner,
not including time spent in the `created` or `pending` statuses.
- [**Cost factor**](#cost-factor): A number based on project visibility.
The number is transformed into minutes and added to the overall quota in the job's top-level namespace.
The value is transformed into minutes and added to the count of used CI/CD minutes
in the job's top-level namespace.
For example:
For example, if a user `alice` runs a pipeline:
- A user, `alice`, runs a pipeline under the `gitlab-org` namespace.
- The CI/CD minutes consumed by each job in the pipeline are added to the
overall consumption for the `gitlab-org` namespace, not the `alice` namespace.
- If a pipeline runs for one of the personal projects for `alice`, the CI/CD minutes
are added to the overall consumption for the `alice` namespace.
- Under the `gitlab-org` namespace, the CI/CD minutes used by each job in the pipeline are
added to the overall consumption for the `gitlab-org` namespace, not the `alice` namespace.
- For one of the personal projects in their namespace, the CI/CD minutes are added
to the overall consumption for the `alice` namespace.
The CI/CD minutes used by one pipeline is the total CI/CD minutes used by all the jobs
that ran in the pipeline. The CI/CD minute usage for a pipeline can be higher than
the duration of the pipeline if many jobs ran at the same time.
that ran in the pipeline. Jobs can run concurrently, so the total CI/CD minutes usage
can be higher than the end-to-end duration of a pipeline.
### Cost factor
The cost factor for a job running on a shared runner is:
The cost factors for jobs running on shared runners on GitLab.com are:
- `0.008` for public projects on GitLab SaaS.
(For every 125 minutes of job time, you accrue 1 CI/CD minute.)
- `0.008` for projects members of GitLab [Open Source program](../../subscriptions/index.md#gitlab-for-open-source).
(For every 125 minutes of job time, you accrue 1 CI/CD minute.)
- `0` for public projects on GitLab self-managed instances.
- `1` for internal or private projects.
- `0.008` for public projects, and projects in the [GitLab for Open Source program](../../subscriptions/index.md#gitlab-for-open-source).
For every 125 minutes of job execution time, you use 1 CI/CD minute.
- `1` for internal and private projects.
The cost factors on self-managed instances are:
- `0` for public projects, so they do not consume CI/CD minutes.
- `1` for internal and private projects.
### Additional costs on GitLab SaaS

View File

@ -10,7 +10,7 @@ Pipeline artifacts are files created by GitLab after a pipeline finishes. Pipeli
different to [job artifacts](job_artifacts.md) because they are not explicitly managed by
`.gitlab-ci.yml` definitions.
Pipeline artifacts are used by the [test coverage visualization feature](../../user/project/merge_requests/test_coverage_visualization.md)
Pipeline artifacts are used by the [test coverage visualization feature](../testing/test_coverage_visualization.md)
to collect coverage information.
## Storage

View File

@ -174,7 +174,7 @@ to stop them from running:
Ensure that errors are detected early in the CI/CD pipeline. A job that takes a very long
time to complete keeps a pipeline from returning a failed status until the job completes.
Design pipelines so that jobs that can [fail fast](../../user/project/merge_requests/fail_fast_testing.md)
Design pipelines so that jobs that can [fail fast](../testing/fail_fast_testing.md)
run earlier. For example, add an early stage and move the syntax, style linting,
Git commit message verification, and similar jobs in there.

View File

@ -0,0 +1,97 @@
---
stage: Verify
group: Pipeline Insights
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/#assignments
---
# Fail Fast Testing **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198550) in GitLab 13.1.
For applications that use RSpec for running tests, we've introduced the `Verify/Failfast`
[template to run subsets of your test suite](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Verify/FailFast.gitlab-ci.yml),
based on the changes in your merge request.
The template uses the [test_file_finder (`tff`) gem](https://gitlab.com/gitlab-org/ci-cd/test_file_finder/)
that accepts a list of files as input, and returns a list of spec (test) files
that it believes to be relevant to the input files.
`tff` is designed for Ruby on Rails projects, so the `Verify/FailFast` template is
configured to run when changes to Ruby files are detected. By default, it runs in
the [`.pre` stage](../yaml/index.md#stage-pre) of a GitLab CI/CD pipeline,
before all other stages.
## Example use case
Fail fast testing is useful when adding new functionality to a project and adding
new automated tests.
Your project could have hundreds of thousands of tests that take a long time to complete.
You may be confident that a new test will pass, but you have to wait for all the tests
to complete to verify it. This could take an hour or more, even when using parallelization.
Fail fast testing gives you a faster feedback loop from the pipeline. It lets you
know quickly that the new tests are passing and the new functionality did not break
other tests.
## Requirements
This template requires:
- A project built in Rails that uses RSpec for testing.
- CI/CD configured to:
- Use a Docker image with Ruby available.
- Use [Merge request pipelines](../pipelines/merge_request_pipelines.md#prerequisites)
- [Merged results pipelines](../pipelines/merged_results_pipelines.md#enable-merged-results-pipelines)
enabled in the project settings.
- A Docker image with Ruby available. The template uses `image: ruby:2.6` by default, but you [can override](../yaml/includes.md#override-included-configuration-values) this.
## Configuring Fast RSpec Failure
We use the following plain RSpec configuration as a starting point. It installs all the
project gems and executes `rspec`, on merge request pipelines only.
```yaml
rspec-complete:
stage: test
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- bundle install
- bundle exec rspec
```
To run the most relevant specs first instead of the whole suite, [`include`](../yaml/index.md#include)
the template by adding the following to your CI/CD configuration:
```yaml
include:
- template: Verify/FailFast.gitlab-ci.yml
```
To customize the job, specific options may be set to override the template. For example, to override the default Docker image:
```yaml
include:
- template: Verify/FailFast.gitlab-ci.yml
rspec-rails-modified-path-specs:
image: custom-docker-image-with-ruby
```
### Example test loads
For illustrative purposes, let's say our Rails app spec suite consists of 100 specs per model for ten models.
If no Ruby files are changed:
- `rspec-rails-modified-paths-specs` does not run any tests.
- `rspec-complete` runs the full suite of 1000 tests.
If one Ruby model is changed, for example `app/models/example.rb`, then `rspec-rails-modified-paths-specs`
runs the 100 tests for `example.rb`:
- If all of these 100 tests pass, then the full `rspec-complete` suite of 1000 tests is allowed to run.
- If any of these 100 tests fail, they fail quickly, and `rspec-complete` does not run any tests.
The final case saves resources and time as the full 1000 test suite does not run.

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -9,18 +9,18 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Use GitLab CI/CD to test the changes included in a feature branch. You can also
display reports or link to important information directly from [merge requests](../../user/project/merge_requests/index.md).
| Feature | Description |
|-------------------------------------------------------------------------------------------------|-------------|
| [Accessibility Testing](accessibility_testing.md) | Automatically report A11y violations for changed pages in merge requests. |
| [Browser Performance Testing](browser_performance_testing.md) | Quickly determine the browser performance impact of pending code changes. |
| [Load Performance Testing](../../user/project/merge_requests/load_performance_testing.md) | Quickly determine the server performance impact of pending code changes. |
| [Code Quality](code_quality.md) | Analyze your source code quality using the [Code Climate](https://codeclimate.com/) analyzer and show the Code Climate report right in the merge request widget area. |
| [Display arbitrary job artifacts](../yaml/index.md#artifactsexpose_as) | Configure CI pipelines with the `artifacts:expose_as` parameter to directly link to selected [artifacts](../pipelines/job_artifacts.md) in merge requests. |
| [Unit test reports](unit_test_reports.md) | Configure your CI jobs to use Unit test reports, and let GitLab display a report on the merge request so that it's easier and faster to identify the failure without having to check the entire job log. |
| [License Compliance](../../user/compliance/license_compliance/index.md) | Manage the licenses of your dependencies. |
| [Metrics Reports](../metrics_reports.md) | Display the Metrics Report on the merge request so that it's fast and easier to identify changes to important metrics. |
| [Test Coverage visualization](../../user/project/merge_requests/test_coverage_visualization.md) | See test coverage results for merge requests, in the file diff. |
| [Fail fast testing](../../user/project/merge_requests/fail_fast_testing.md#fail-fast-testing) | Run a subset of your RSpec test suite, so failed tests stop the pipeline before the full suite of tests run, saving resources. |
| Feature | Description |
|-------------------------------------------------------------------------|-------------|
| [Accessibility Testing](accessibility_testing.md) | Automatically report A11y violations for changed pages in merge requests. |
| [Browser Performance Testing](browser_performance_testing.md) | Quickly determine the browser performance impact of pending code changes. |
| [Load Performance Testing](load_performance_testing.md) | Quickly determine the server performance impact of pending code changes. |
| [Code Quality](code_quality.md) | Analyze your source code quality using the [Code Climate](https://codeclimate.com/) analyzer and show the Code Climate report right in the merge request widget area. |
| [Display arbitrary job artifacts](../yaml/index.md#artifactsexpose_as) | Configure CI pipelines with the `artifacts:expose_as` parameter to directly link to selected [artifacts](../pipelines/job_artifacts.md) in merge requests. |
| [Unit test reports](unit_test_reports.md) | Configure your CI jobs to use Unit test reports, and let GitLab display a report on the merge request so that it's easier and faster to identify the failure without having to check the entire job log. |
| [License Compliance](../../user/compliance/license_compliance/index.md) | Manage the licenses of your dependencies. |
| [Metrics Reports](metrics_reports.md) | Display the Metrics Report on the merge request so that it's fast and easier to identify changes to important metrics. |
| [Test Coverage visualization](test_coverage_visualization.md) | See test coverage results for merge requests, in the file diff. |
| [Fail fast testing](fail_fast_testing.md) | Run a subset of your RSpec test suite, so failed tests stop the pipeline before the full suite of tests run, saving resources. |
## Security Reports **(ULTIMATE)**

View File

@ -0,0 +1,201 @@
---
stage: Verify
group: Pipeline Insights
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/#assignments
---
# Load Performance Testing **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10683) in GitLab 13.2.
With Load Performance Testing, you can test the impact of any pending code changes
to your application's backend in [GitLab CI/CD](../index.md).
GitLab uses [k6](https://k6.io/), a free and open source
tool, for measuring the system performance of applications under
load.
Unlike [Browser Performance Testing](browser_performance_testing.md), which is
used to measure how web sites perform in client browsers, Load Performance Testing
can be used to perform various types of [load tests](https://k6.io/docs/#use-cases)
against application endpoints such as APIs, Web Controllers, and so on.
This can be used to test how the backend or the server performs at scale.
For example, you can use Load Performance Testing to perform many concurrent
GET calls to a popular API endpoint in your application to see how it performs.
## How Load Performance Testing works
First, define a job in your `.gitlab-ci.yml` file that generates the
[Load Performance report artifact](../yaml/artifacts_reports.md#artifactsreportsload_performance).
GitLab checks this report, compares key load performance metrics
between the source and target branches, and then shows the information in a merge request widget:
![Load Performance Widget](img/load_performance_testing.png)
Next, you need to configure the test environment and write the k6 test.
The key performance metrics that the merge request widget shows after the test completes are:
- Checks: The percentage pass rate of the [checks](https://k6.io/docs/using-k6/checks) configured in the k6 test.
- TTFB P90: The 90th percentile of how long it took to start receiving responses, aka the [Time to First Byte](https://en.wikipedia.org/wiki/Time_to_first_byte) (TTFB).
- TTFB P95: The 95th percentile for TTFB.
- RPS: The average requests per second (RPS) rate the test was able to achieve.
NOTE:
If the Load Performance report has no data to compare, such as when you add the
Load Performance job in your `.gitlab-ci.yml` for the very first time,
the Load Performance report widget doesn't display. It must have run at least
once on the target branch (`main`, for example), before it displays in a
merge request targeting that branch.
## Configure the Load Performance Testing job
Configuring your Load Performance Testing job can be broken down into several distinct parts:
- Determine the test parameters such as throughput, and so on.
- Set up the target test environment for load performance testing.
- Design and write the k6 test.
### Determine the test parameters
The first thing you need to do is determine the [type of load test](https://k6.io/docs/test-types/introduction)
you want to run, and how it will run (for example, the number of users, throughput, and so on).
Refer to the [k6 docs](https://k6.io/docs/), especially the [k6 testing guides](https://k6.io/docs/testing-guides),
for guidance on the above and more.
### Test Environment setup
A large part of the effort around load performance testing is to prepare the target test environment
for high loads. You should ensure it's able to handle the
[throughput](https://k6.io/blog/monthly-visits-concurrent-users) it will be tested with.
It's also typically required to have representative test data in the target environment
for the load performance test to use.
We strongly recommend [not running these tests against a production environment](https://k6.io/our-beliefs#load-test-in-a-pre-production-environment).
### Write the load performance test
After the environment is prepared, you can write the k6 test itself. k6 is a flexible
tool and can be used to run [many kinds of performance tests](https://k6.io/docs/test-types/introduction).
Refer to the [k6 documentation](https://k6.io/docs/) for detailed information on how to write tests.
### Configure the test in GitLab CI/CD
When your k6 test is ready, the next step is to configure the load performance
testing job in GitLab CI/CD. The easiest way to do this is to use the
[`Verify/Load-Performance-Testing.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Verify/Load-Performance-Testing.gitlab-ci.yml)
template that is included with GitLab.
NOTE:
For large scale k6 tests you need to ensure the GitLab Runner instance performing the actual
test is able to handle running the test. Refer to [k6's guidance](https://k6.io/docs/testing-guides/running-large-tests#hardware-considerations)
for spec details. The [default shared GitLab.com runners](../runners/saas/linux_saas_runner.md)
likely have insufficient specs to handle most large k6 tests.
This template runs the
[k6 Docker container](https://hub.docker.com/r/loadimpact/k6/) in the job and provides several ways to customize the
job.
An example configuration workflow:
1. Set up GitLab Runner to run Docker containers, like the
[Docker-in-Docker workflow](../docker/using_docker_build.md#use-docker-in-docker).
1. Configure the default Load Performance Testing CI/CD job in your `.gitlab-ci.yml` file.
You need to include the template and configure it with CI/CD variables:
```yaml
include:
template: Verify/Load-Performance-Testing.gitlab-ci.yml
load_performance:
variables:
K6_TEST_FILE: <PATH TO K6 TEST FILE IN PROJECT>
```
The above example creates a `load_performance` job in your CI/CD pipeline that runs
the k6 test.
NOTE:
For Kubernetes setups a different template should be used: [`Jobs/Load-Performance-Testing.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml).
k6 has [various options](https://k6.io/docs/using-k6/options) to configure how it will run tests, such as what throughput (RPS) to run with,
how long the test should run, and so on. Almost all options can be configured in the test itself, but as
you can also pass command line options via the `K6_OPTIONS` variable.
For example, you can override the duration of the test with a CLI option:
```yaml
include:
template: Verify/Load-Performance-Testing.gitlab-ci.yml
load_performance:
variables:
K6_TEST_FILE: <PATH TO K6 TEST FILE IN PROJECT>
K6_OPTIONS: '--duration 30s'
```
GitLab only displays the key performance metrics in the MR widget if k6's results are saved
via [summary export](https://k6.io/docs/results-visualization/json#summary-export)
as a [Load Performance report artifact](../yaml/artifacts_reports.md#artifactsreportsload_performance).
The latest Load Performance artifact available is always used, using the
summary values from the test.
If [GitLab Pages](../../user/project/pages/index.md) is enabled, you can view the report directly in your browser.
### Load Performance testing in Review Apps
The CI/CD YAML configuration example above works for testing against static environments,
but it can be extended to work with [review apps](../review_apps/index.md) or
[dynamic environments](../environments/index.md) with a few extra steps.
The best approach is to capture the dynamic URL in a [`.env` file](https://docs.docker.com/compose/env-file/)
as a job artifact to be shared, then use a custom CI/CD variable we've provided named `K6_DOCKER_OPTIONS`
to configure the k6 Docker container to use the file. With this, k6 can then use any
environment variables from the `.env` file in scripts using standard JavaScript,
such as: ``http.get(`${__ENV.ENVIRONMENT_URL}`)``.
For example:
1. In the `review` job:
1. Capture the dynamic URL and save it into a `.env` file, for example, `echo "ENVIRONMENT_URL=$CI_ENVIRONMENT_URL" >> review.env`.
1. Set the `.env` file to be a [job artifact](../pipelines/job_artifacts.md).
1. In the `load_performance` job:
1. Set it to depend on the review job, so it inherits the environment file.
1. Set the `K6_DOCKER_OPTIONS` variable with the [Docker CLI option for environment files](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file), for example `--env-file review.env`.
1. Configure the k6 test script to use the environment variable in it's steps.
Your `.gitlab-ci.yml` file might be similar to:
```yaml
stages:
- deploy
- performance
include:
template: Verify/Load-Performance-Testing.gitlab-ci.yml
review:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_SLUG
url: http://$CI_ENVIRONMENT_SLUG.example.com
script:
- run_deploy_script
- echo "ENVIRONMENT_URL=$CI_ENVIRONMENT_URL" >> review.env
artifacts:
paths:
- review.env
rules:
- if: $CI_COMMIT_BRANCH # Modify to match your pipeline rules, or use `only/except` if needed.
load_performance:
dependencies:
- review
variables:
K6_DOCKER_OPTIONS: '--env-file review.env'
rules:
- if: $CI_COMMIT_BRANCH # Modify to match your pipeline rules, or use `only/except` if needed.
```

View File

@ -0,0 +1,68 @@
---
stage: Verify
group: Pipeline Insights
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/#assignments
---
# Metrics Reports **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9788) in GitLab 11.10. Requires GitLab Runner 11.10 and above.
GitLab provides a lot of great reporting tools for things like [merge requests](../../user/project/merge_requests/index.md) - [Unit test reports](unit_test_reports.md), [code quality](code_quality.md), and performance tests. While JUnit is a great open framework for tests that "pass" or "fail", it is also important to see other types of metrics from a given change.
You can configure your job to use custom Metrics Reports, and GitLab displays a report on the merge request so that it's easier and faster to identify changes without having to check the entire log.
![Metrics Reports](img/metrics_reports_v13_0.png)
## Use cases
Consider the following examples of data that can use Metrics Reports:
1. Memory usage
1. Load testing results
1. Code complexity
1. Code coverage stats
## How it works
Metrics for a branch are read from the latest metrics report artifact (default filename: `metrics.txt`) as string values.
For an MR, the values of these metrics from the feature branch are compared to the values from the target branch. Then they are displayed in the MR widget in this order:
- Existing metrics with changed values.
- Metrics that have been added by the MR. Marked with a **New** badge.
- Metrics that have been removed by the MR. Marked with a **Removed** badge.
- Existing metrics with unchanged values.
## How to set it up
Add a job that creates a [metrics report](../yaml/artifacts_reports.md#artifactsreportsmetrics) (default filename: `metrics.txt`). The file should conform to the [OpenMetrics](https://openmetrics.io/) format.
For example:
```yaml
metrics:
script:
- echo 'metric_name metric_value' > metrics.txt
artifacts:
reports:
metrics: metrics.txt
```
## Advanced Example
An advanced example of an OpenMetrics text file (from the [Prometheus documentation](https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md#text-format-example))
renders in the merge request widget as:
![Metrics Reports Advanced](img/metrics_reports_advanced_v13_0.png)
## Troubleshooting
### Metrics reports did not change
You can see `Metrics reports did not change` when trying to view metrics reports in merge requests. Reasons for this are:
- The target branch for the merge request doesn't have a baseline metrics report for comparison.
- You don't have GitLab license at the Premium tier or above.
There is [an issue open](https://gitlab.com/gitlab-org/gitlab/-/issues/343065) to improve this message.

View File

@ -0,0 +1,441 @@
---
stage: Verify
group: Pipeline Insights
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/#assignments
---
# Test coverage visualization **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/249811) in GitLab 13.5.
With the help of [GitLab CI/CD](../index.md), you can collect the test
coverage information of your favorite testing or coverage-analysis tool, and visualize
this information inside the file diff view of your merge requests (MRs). This will allow you
to see which lines are covered by tests, and which lines still require coverage, before the
MR is merged.
![Test Coverage Visualization Diff View](img/test_coverage_visualization_v12_9.png)
## How test coverage visualization works
Collecting the coverage information is done via GitLab CI/CD's
[artifacts reports feature](../yaml/index.md#artifactsreports).
You can specify one or more coverage reports to collect, including wildcard paths.
GitLab then takes the coverage information in all the files and combines it
together. Coverage files are parsed in a background job so there can be a delay
between pipeline completion and the visualization loading on the page.
For the coverage analysis to work, you have to provide a properly formatted
[Cobertura XML](https://cobertura.github.io/cobertura/) report to
[`artifacts:reports:coverage_report`](../yaml/artifacts_reports.md#artifactsreportscoverage_report).
This format was originally developed for Java, but most coverage analysis frameworks
for other languages have plugins to add support for it, like:
- [simplecov-cobertura](https://rubygems.org/gems/simplecov-cobertura) (Ruby)
- [gocover-cobertura](https://github.com/boumenot/gocover-cobertura) (Golang)
Other coverage analysis frameworks support the format out of the box, for example:
- [Istanbul](https://istanbul.js.org/docs/advanced/alternative-reporters/#cobertura) (JavaScript)
- [Coverage.py](https://coverage.readthedocs.io/en/coverage-5.0.4/cmd.html#xml-reporting) (Python)
- [PHPUnit](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/master/src/textui.rst#command-line-options) (PHP)
Once configured, if you create a merge request that triggers a pipeline which collects
coverage reports, the coverage is shown in the diff view. This includes reports
from any job in any stage in the pipeline. The coverage displays for each line:
- `covered` (green): lines which have been checked at least once by tests
- `no test coverage` (orange): lines which are loaded but never executed
- no coverage information: lines which are non-instrumented or not loaded
Hovering over the coverage bar provides further information, such as the number
of times the line was checked by tests.
Uploading a test coverage report does not enable:
- [Test coverage results in merge requests](../pipelines/settings.md#merge-request-test-coverage-results).
- [Code coverage history](../pipelines/settings.md#view-code-coverage-history).
You must configure these separately.
### Limits
A limit of 100 `<source>` nodes for Cobertura format XML files applies. If your Cobertura report exceeds
100 nodes, there can be mismatches or no matches in the merge request diff view.
A single Cobertura XML file can be no more than 10MiB. For large projects, split the Cobertura XML into
smaller files. See [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/328772) for more details.
When submitting many files, it can take a few minutes for coverage to show on a merge request.
The visualization only displays after the pipeline is complete. If the pipeline has
a [blocking manual job](../jobs/job_control.md#types-of-manual-jobs), the
pipeline waits for the manual job before continuing and is not considered complete.
The visualization cannot be displayed if the blocking manual job did not run.
### Artifact expiration
By default, the [pipeline artifact](../pipelines/pipeline_artifacts.md#storage) used
to draw the visualization on the merge request expires **one week** after creation.
### Coverage report from child pipeline
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/363301) in GitLab 15.1 [with a flag](../../administration/feature_flags.md). Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `ci_child_pipeline_coverage_reports`.
On GitLab.com, this feature is not available.
The feature is not ready for production use.
If the test coverage is created in jobs that are in a child pipeline, the parent pipeline must use
`strategy: depend`.
```yaml
child_test_pipeline:
trigger:
include:
- local: path/to/child_pipeline.yml
- template: Security/SAST.gitlab-ci.yml
strategy: depend
```
### Automatic class path correction
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217664) in GitLab 13.8.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/284822) in GitLab 13.9.
The coverage report properly matches changed files only if the `filename` of a `class` element
contains the full path relative to the project root. However, in some coverage analysis frameworks,
the generated Cobertura XML has the `filename` path relative to the class package directory instead.
To make an intelligent guess on the project root relative `class` path, the Cobertura XML parser
attempts to build the full path by:
- Extracting a portion of the `source` paths from the `sources` element and combining them with the
class `filename` path.
- Checking if the candidate path exists in the project.
- Using the first candidate that matches as the class full path.
#### Path correction example
As an example, a project with:
- A full path of `test-org/test-project`.
- The following files relative to the project root:
```shell
Auth/User.cs
Lib/Utils/User.cs
src/main/java
```
In the:
- Cobertura XML, the `filename` attribute in the `class` element assumes the value is a relative
path to the project's root:
```xml
<class name="packet.name" filename="src/main/java" line-rate="0.0" branch-rate="0.0" complexity="5">
```
- `sources` from Cobertura XML, the following paths in the format
`<CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/...`:
```xml
<sources>
<source>/builds/test-org/test-project/Auth</source>
<source>/builds/test-org/test-project/Lib/Utils</source>
</sources>
```
The parser:
- Extracts `Auth` and `Lib/Utils` from the `sources` and uses these to determine the `class` path
relative to the project root.
- Combines these extracted `sources` and the class filename. For example, if there is a `class`
element with the `filename` value of `User.cs`, the parser takes the first candidate path that
matches, which is `Auth/User.cs`.
- For each `class` element, attempts to look for a match for each extracted `source` path up to
100 iterations. If it reaches this limit without finding a matching path in the file tree, the
class is not included in the final coverage report.
NOTE:
Automatic class path correction only works on `source` paths in the format `<CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/...`.
The `source` is ignored if the path does not follow this pattern. The parser assumes that the
`filename` of a `class` element contains the full path relative to the project root.
## Example test coverage configurations
This section provides test coverage configuration examples for different programming languages. You can also see a working example in
the [`coverage-report`](https://gitlab.com/gitlab-org/ci-sample-projects/coverage-report/) demonstration project.
### JavaScript example
The following [`.gitlab-ci.yml`](../yaml/index.md) example uses [Mocha](https://mochajs.org/)
JavaScript testing and [nyc](https://github.com/istanbuljs/nyc) coverage-tooling to
generate the coverage artifact:
```yaml
test:
script:
- npm install
- npx nyc --reporter cobertura mocha
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
```
### Java and Kotlin examples
#### Maven example
The following [`.gitlab-ci.yml`](../yaml/index.md) example for Java or Kotlin uses [Maven](https://maven.apache.org/)
to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to
generate the coverage artifact.
You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image.
GitLab expects the artifact in the Cobertura format, so you have to execute a few
scripts before uploading it. The `test-jdk11` job tests the code and generates an
XML artifact. The `coverage-jdk-11` job converts the artifact into a Cobertura report:
```yaml
test-jdk11:
stage: test
image: maven:3.6.3-jdk-11
script:
- mvn $MAVEN_CLI_OPTS clean org.jacoco:jacoco-maven-plugin:prepare-agent test jacoco:report
artifacts:
paths:
- target/site/jacoco/jacoco.xml
coverage-jdk11:
# Must be in a stage later than test-jdk11's stage.
# The `visualize` stage does not exist by default.
# Please define it first, or choose an existing stage like `deploy`.
stage: visualize
image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
script:
# convert report from jacoco to cobertura, using relative project path
- python /opt/cover2cover.py target/site/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > target/site/cobertura.xml
needs: ["test-jdk11"]
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: target/site/cobertura.xml
```
#### Gradle example
The following [`.gitlab-ci.yml`](../yaml/index.md) example for Java or Kotlin uses [Gradle](https://gradle.org/)
to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to
generate the coverage artifact.
You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image.
GitLab expects the artifact in the Cobertura format, so you have to execute a few
scripts before uploading it. The `test-jdk11` job tests the code and generates an
XML artifact. The `coverage-jdk-11` job converts the artifact into a Cobertura report:
```yaml
test-jdk11:
stage: test
image: gradle:6.6.1-jdk11
script:
- 'gradle test jacocoTestReport' # jacoco must be configured to create an xml report
artifacts:
paths:
- build/jacoco/jacoco.xml
coverage-jdk11:
# Must be in a stage later than test-jdk11's stage.
# The `visualize` stage does not exist by default.
# Please define it first, or chose an existing stage like `deploy`.
stage: visualize
image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
script:
# convert report from jacoco to cobertura, using relative project path
- python /opt/cover2cover.py build/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > build/cobertura.xml
needs: ["test-jdk11"]
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: build/cobertura.xml
```
### Python example
The following [`.gitlab-ci.yml`](../yaml/index.md) example for Python uses [pytest-cov](https://pytest-cov.readthedocs.io/) to collect test coverage data and [coverage.py](https://coverage.readthedocs.io/) to convert the report to use full relative paths.
The information isn't displayed without the conversion.
This example assumes that the code for your package is in `src/` and your tests are in `tests.py`:
```yaml
run tests:
stage: test
image: python:3
script:
- pip install pytest pytest-cov
- coverage run -m pytest
- coverage report
- coverage xml
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
```
### PHP example
The following [`.gitlab-ci.yml`](../yaml/index.md) example for PHP uses [PHPUnit](https://phpunit.readthedocs.io/)
to collect test coverage data and generate the report.
With a minimal [`phpunit.xml`](https://phpunit.readthedocs.io/en/9.5/configuration.html) file (you may reference
[this example repository](https://gitlab.com/yookoala/code-coverage-visualization-with-php/)), you can run the test and
generate the `coverage.xml`:
```yaml
run tests:
stage: test
image: php:latest
variables:
XDEBUG_MODE: coverage
before_script:
- apt-get update && apt-get -yq install git unzip zip libzip-dev zlib1g-dev
- docker-php-ext-install zip
- pecl install xdebug && docker-php-ext-enable xdebug
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php --install-dir=/usr/local/bin --filename=composer
- composer install
- composer require --dev phpunit/phpunit phpunit/php-code-coverage
script:
- php ./vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.cobertura.xml
```
[Codeception](https://codeception.com/), through PHPUnit, also supports generating Cobertura report with
[`run`](https://codeception.com/docs/reference/Commands#run). The path for the generated file
depends on the `--coverage-cobertura` option and [`paths`](https://codeception.com/docs/reference/Configuration#paths)
configuration for the [unit test suite](https://codeception.com/docs/05-UnitTests). Configure `.gitlab-ci.yml`
to find Cobertura in the appropriate path.
### C/C++ example
The following [`.gitlab-ci.yml`](../yaml/index.md) example for C/C++ with
`gcc` or `g++` as the compiler uses [`gcovr`](https://gcovr.com/en/stable/) to generate the coverage
output file in Cobertura XML format.
This example assumes:
- That the `Makefile` is created by `cmake` in the `build` directory,
within another job in a previous stage.
(If you use `automake` to generate the `Makefile`,
then you need to call `make check` instead of `make test`.)
- `cmake` (or `automake`) has set the compiler option `--coverage`.
```yaml
run tests:
stage: test
script:
- cd build
- make test
- gcovr --xml-pretty --exclude-unreachable-branches --print-summary -o coverage.xml --root ${CI_PROJECT_DIR}
coverage: /^\s*lines:\s*\d+.\d+\%/
artifacts:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
expire_in: 2 days
reports:
coverage_report:
coverage_format: cobertura
path: build/coverage.xml
```
### Go example
The following [`.gitlab-ci.yml`](../yaml/index.md) example for Go uses:
- [`go test`](https://go.dev/doc/tutorial/add-a-test) to run tests.
- [`gocover-cobertura`](https://github.com/boumenot/gocover-cobertura) to convert Go's coverage profile into the Cobertura XML format.
This example assumes that [Go modules](https://go.dev/ref/mod)
are being used. Please note that the `-covermode count` option does not work with the `-race` flag.
If you want to generate code coverage while also using the `-race` flag, you must switch to
`-covermode atomic` which is slower than `-covermode count`. See [this blog post](https://go.dev/blog/cover)
for more details.
```yaml
run tests:
stage: test
image: golang:1.17
script:
- go install
- go test ./... -coverprofile=coverage.txt -covermode count
- go get github.com/boumenot/gocover-cobertura
- go run github.com/boumenot/gocover-cobertura < coverage.txt > coverage.xml
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
```
### Ruby example
The following [`.gitlab-ci.yml`](../yaml/index.md) example for Ruby uses
- [`rspec`](https://rspec.info/) to run tests.
- [`simplecov`](https://github.com/simplecov-ruby/simplecov) and [`simplecov-cobertura`](https://github.com/dashingrocket/simplecov-cobertura)
to record the coverage profile and create a report in the Cobertura XML format.
This example assumes:
- That [`bundler`](https://bundler.io/) is being used for dependency management.
The `rspec`, `simplecov` and `simplecov-cobertura` gems have been added to your `Gemfile`.
- The `CoberturaFormatter` has been added to your `SimpleCov.formatters`
configuration within the `spec_helper.rb` file.
```yaml
run tests:
stage: test
image: ruby:3.1
script:
- bundle install
- bundle exec rspec
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/coverage.xml
```
## Troubleshooting
### Test coverage visualization not displayed
If the test coverage visualization is not displayed in the diff view, you can check
the coverage report itself and verify that:
- The file you are viewing in the diff view is mentioned in the coverage report.
- The `source` and `filename` nodes in the report follows the [expected structure](#automatic-class-path-correction)
to match the files in your repository.
Report artifacts are not downloadable by default. If you want the report to be downloadable
from the job details page, add your coverage report to the artifact `paths`:
```yaml
artifacts:
paths:
- coverage/cobertura-coverage.xml
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
```

View File

@ -100,7 +100,7 @@ instead.
Use `coverage_report` to collect coverage report in Cobertura format.
The `cobertura` report collects [Cobertura coverage XML files](../../user/project/merge_requests/test_coverage_visualization.md).
The `cobertura` report collects [Cobertura coverage XML files](../testing/test_coverage_visualization.md).
Cobertura was originally developed for Java, but there are many third-party ports for other languages such as
JavaScript, Python, and Ruby.
@ -116,7 +116,7 @@ artifacts:
The collected coverage report is uploaded to GitLab as an artifact.
GitLab can display the results of coverage report in the merge request
[diff annotations](../../user/project/merge_requests/test_coverage_visualization.md).
[diff annotations](../testing/test_coverage_visualization.md).
## `artifacts:reports:codequality`
@ -131,7 +131,7 @@ GitLab can display the results of:
- Only one report in:
- The merge request [diff annotations](../testing/code_quality.md#code-quality-in-diff-view).
Track progress on adding support for multiple reports in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/328257).
- The [full report](../metrics_reports.md). Track progress on adding support for multiple reports in
- The [full report](../testing/metrics_reports.md). Track progress on adding support for multiple reports in
[this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/9014).
## `artifacts:reports:container_scanning` **(ULTIMATE)**
@ -263,21 +263,21 @@ GitLab can display the results of one or more reports in:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35260) in GitLab 13.2.
> - Requires GitLab Runner 11.5 and above.
The `load_performance` report collects [Load Performance Testing metrics](../../user/project/merge_requests/load_performance_testing.md).
The `load_performance` report collects [Load Performance Testing metrics](../testing/load_performance_testing.md).
The report is uploaded to GitLab as an artifact.
GitLab can display the results of only one report in the merge request
[load testing widget](../../user/project/merge_requests/load_performance_testing.md#how-load-performance-testing-works).
[load testing widget](../testing/load_performance_testing.md#how-load-performance-testing-works).
GitLab cannot display the combined results of multiple `load_performance` reports.
## `artifacts:reports:metrics` **(PREMIUM)**
The `metrics` report collects [Metrics](../metrics_reports.md). The collected Metrics report uploads to GitLab as an
The `metrics` report collects [Metrics](../testing/metrics_reports.md). The collected Metrics report uploads to GitLab as an
artifact.
GitLab can display the results of one or more reports in the merge request
[metrics reports widget](../../ci/metrics_reports.md#metrics-reports).
[metrics reports widget](../testing/metrics_reports.md#metrics-reports).
## `artifacts:reports:requirements` **(ULTIMATE)**

View File

@ -3519,6 +3519,52 @@ in that container.
- [Run your CI/CD jobs in Docker containers](../docker/using_docker_images.md).
- [Use Docker to build Docker images](../docker/using_docker_build.md).
#### `service:pull_policy`
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21619) in GitLab 15.1 [with a flag](../../administration/feature_flags.md) named `ci_docker_image_pull_policy`. Disabled by default.
> - Requires GitLab Runner 15.1 or later.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `ci_docker_image_pull_policy`.
The feature is not ready for production use.
The pull policy that the runner uses to fetch the Docker image.
**Keyword type**: Job keyword. You can use it only as part of a job or in the [`default` section](#default).
**Possible inputs**:
- A single pull policy, or multiple pull policies in an array.
Can be `always`, `if-not-present`, or `never`.
**Examples of `service:pull_policy`**:
```yaml
job1:
script: echo "A single pull policy."
services:
- name: postgres:11.6
pull_policy: if-not-present
job2:
script: echo "Multiple pull policies."
services:
- name: postgres:11.6
pull_policy: [always, if-not-present]
```
**Additional details**:
- If the runner does not support the defined pull policy, the job fails with an error similar to:
`ERROR: Job failed (system failure): the configured PullPolicies ([always]) are not allowed by AllowedPullPolicies ([never])`.
**Related topics**:
- [Run your CI/CD jobs in Docker containers](../docker/using_docker_images.md).
- [How runner pull policies work](https://docs.gitlab.com/runner/executors/docker.html#how-pull-policies-work).
- [Using multiple pull policies](https://docs.gitlab.com/runner/executors/docker.html#using-multiple-pull-policies).
### `stage`
Use `stage` to define which [stage](#stages) a job runs in. Jobs in the same

View File

@ -150,3 +150,23 @@ To [include](index.md#include) it:
include:
- template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'
```
## Troubleshooting
### Merge request stuck with `Checking pipeline status.` message
If a merge request displays `Checking pipeline status.`, but the message never goes
away (the "spinner" never stops spinning), it might be due to `workflow:rules`.
This issue can happen if a project has [**Pipelines must succeed**](../../user/project/merge_requests/merge_when_pipeline_succeeds.md#only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds)
enabled, but the `workflow:rules` prevent a pipeline from running for the merge request.
For example, with this workflow, merge requests cannot be merged, because no
pipeline can run:
```yaml
workflow:
rules:
- changes:
- .gitlab/**/**.md
when: never
```

View File

@ -29,7 +29,7 @@ consistent performance of GitLab. Refer to the [Index](#performance-documentatio
- [Browser performance testing guidelines](../ci/testing/browser_performance_testing.md)
- [`gdk measure` and `gdk measure-workflow`](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/gdk_commands.md#measure-performance)
- QA:
- [Load performance testing](../user/project/merge_requests/load_performance_testing.md)
- [Load performance testing](../ci/testing/load_performance_testing.md)
- [GitLab Performance Tool project](https://gitlab.com/gitlab-org/quality/performance)
- [Review apps performance metrics](../development/testing_guide/review_apps.md#performance-metrics)
- Monitoring & Overview:
@ -581,7 +581,7 @@ called `memory-on-boot`. ([Read an example job.](https://gitlab.com/gitlab-org/g
You may find the results:
- On the merge request **Overview** tab, in the merge request reports area, in the
**Metrics Reports** [dropdown list](../ci/metrics_reports.md).
**Metrics Reports** [dropdown list](../ci/testing/metrics_reports.md).
- In the `memory-on-boot` artifacts for a full report and a dependency breakdown.
`derailed_benchmarks` also provides other methods to investigate memory. To learn more,

View File

@ -357,7 +357,7 @@ Any browser performance differences between the source and target branches are a
> Introduced in GitLab 13.2.
Auto [Load Performance Testing](../../user/project/merge_requests/load_performance_testing.md)
Auto [Load Performance Testing](../../ci/testing/load_performance_testing.md)
measures the server performance of an application with the
[k6 container](https://hub.docker.com/r/loadimpact/k6/),
creates a JSON report including several key result metrics, and
@ -368,7 +368,7 @@ written that's tailored to your specific application. The test also needs to be
configured so it can pick up the environment's dynamic URL via a CI/CD variable.
Any load performance test result differences between the source and target branches are also
[shown in the merge request widget](../../user/project/merge_requests/load_performance_testing.md).
[shown in the merge request widget](../../user/project/merge_requests/widgets.md).
## Auto Deploy

View File

@ -28,13 +28,11 @@ You can install your applications manually as shown in the following sections, o
installation.
Although, the [Cluster management project template](management_project_template.md) still
requires that you manually do the last steps of these sections,
[Enable Prometheus integration for your cluster](#enable-prometheus-integration-for-your-cluster)
or [Enable Elastic Stack integration for your cluster](#enable-elastic-stack-integration-for-your-cluster)
depending on which application you are installing. [An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/326565)
requires that you manually do the last steps of this section,
[Enable Prometheus integration for your cluster](#enable-prometheus-integration-for-your-cluster). [An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/326565)
to automate this step.
Prometheus and Elastic Stack cluster integrations can only be enabled for clusters [connected through cluster certificates](../project/clusters/add_existing_cluster.md).
Prometheus cluster integrations can only be enabled for clusters [connected through cluster certificates](../project/clusters/add_existing_cluster.md).
To enable Prometheus for your cluster connected through the [GitLab agent](agent/index.md), you can [integrate it manually](../project/integrations/prometheus.md#manual-configuration-of-prometheus).
@ -100,70 +98,3 @@ To enable the Prometheus integration for your cluster:
1. Check the **Enable Prometheus integration** checkbox.
1. Select **Save changes**.
1. Go to the **Health** tab to see your cluster's metrics.
## Elastic Stack cluster integration **(FREE SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61077) in GitLab 13.12.
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346485) in GitLab 14.7.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/360182) behind a [feature flag](../../administration/feature_flags.md) named `monitor_logging` in GitLab 15.0. Disabled by default.
WARNING:
This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346485)
in GitLab 14.7.
It will be removed completely in GitLab 15.2.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `monitor_logging`.
On GitLab.com, this feature is not available.
This feature is not recommended for production use.
You can integrate your cluster with [Elastic
Stack](https://www.elastic.co/elastic-stack/) to index and [query your pod
logs](../project/clusters/kubernetes_pod_logs.md).
### Elastic Stack Prerequisites
To use this integration:
1. Elasticsearch 7.x or must be installed in your cluster in the
`gitlab-managed-apps` namespace.
1. The `Service` resource must be called `elastic-stack-elasticsearch-master`
and expose the Elasticsearch API on port `9200`.
1. The logs are expected to be [Filebeat container logs](https://www.elastic.co/guide/en/beats/filebeat/7.16/filebeat-input-container.html)
following the [7.x log structure](https://www.elastic.co/guide/en/beats/filebeat/7.16/exported-fields-log.html)
and include [Kubernetes metadata](https://www.elastic.co/guide/en/beats/filebeat/7.16/add-kubernetes-metadata.html).
You can manage your Elastic Stack however you like, but as an example, you can
use [this Elastic Stack chart](https://gitlab.com/gitlab-org/charts/elastic-stack) to get up and
running:
```shell
# Create the required Kubernetes namespace
kubectl create namespace gitlab-managed-apps
# Download Helm chart values that is compatible with the requirements above.
# These are included in the Cluster Management project template.
wget https://gitlab.com/gitlab-org/project-templates/cluster-management/-/raw/master/applications/elastic-stack/values.yaml
# Add the GitLab Helm chart repository
helm repo add gitlab https://charts.gitlab.io
# Install Elastic Stack
helm install elastic-stack gitlab/elastic-stack -n gitlab-managed-apps --values values.yaml
```
### Enable Elastic Stack integration for your cluster
To enable the Elastic Stack integration for your cluster:
1. Go to the cluster's page:
- For a [project-level cluster](../project/clusters/index.md), navigate to your project's
**Infrastructure > Kubernetes clusters**.
- For a [group-level cluster](../group/clusters/index.md), navigate to your group's
**Kubernetes** page.
- For an [instance-level cluster](../instance/clusters/index.md), navigate to your instance's
**Kubernetes** page.
1. Select the **Integrations** tab.
1. Check the **Enable Elastic Stack integration** checkbox.
1. Select **Save changes**.
1. Go to the **Health** tab to see your cluster's metrics.

View File

@ -670,16 +670,23 @@ The most popular public email domains cannot be restricted, such as:
## Restrict Git access protocols
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/365601) in GitLab 15.1.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/365601) in GitLab 15.1 [with a flag](../../administration/feature_flags.md) named `group_level_git_protocol_control`. Disabled by default.
Access to the group's repositories via SSH or HTTP(S) can be restricted to individual protocols. This setting is overridden by the instance setting configured in the GitLab Admin.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to
[enable the feature flag](../../administration/feature_flags.md) named `group_level_git_protocol_control`. On GitLab.com,
this feature is available.
To alter the permitted Git access protocols:
You can set the permitted protocols used to access a group's repositories to either SSH, HTTPS, or both. This setting
is disabled when the [instance setting](../admin_area/settings/visibility_and_access_controls.md#configure-enabled-git-access-protocols) is
configured by an administrator.
To change the permitted Git access protocols for a group:
1. Go to the group's **Settings > General** page.
1. Expand the **Permissions and group features** section.
1. Choose the allowed protocols from **Enable Git access protocols**
1. Select **Save changes**
1. Choose the permitted protocols from **Enabled Git access protocols**.
1. Select **Save changes**.
## Group file templates **(PREMIUM)**

View File

@ -33,9 +33,6 @@ above the log file data, depending on your configuration:
- **Namespace** - Select the environment to display. Users with Maintainer or
greater [permissions](../../permissions.md) can also see pods in the
`gitlab-managed-apps` namespace.
- **Search** - Only available if the [Elastic Stack integration](../../clusters/integrations.md#elastic-stack-cluster-integration) is enabled.
- **Select time range** - Select the range of time to display.
Only available if the [Elastic Stack integration](../../clusters/integrations.md#elastic-stack-cluster-integration) is enabled.
- **Scroll to bottom** **{scroll_down}** - Scroll to the end of the displayed logs.
- **Refresh** **{retry}** - Reload the displayed logs.
@ -76,8 +73,6 @@ The **Log Explorer** lets you filter the logs by:
- Pods.
- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/5769), environments.
- [From GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21656),
[full text search](#full-text-search).
- [From GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/issues/197879), dates.
- [From GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/208790), managed apps.
@ -89,33 +84,3 @@ Support for pods with multiple containers is coming
Support for historical data is coming
[in a future release](https://gitlab.com/gitlab-org/gitlab/-/issues/196191).
### Filter by date
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197879) in GitLab 12.8.
When you enable [Elastic Stack](../../clusters/integrations.md#elastic-stack-cluster-integration)
on your cluster, you can filter logs displayed in the **Log Explorer** by date.
Select **Show last** in the **Log Explorer** to see the available options.
### Full text search
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21656) in GitLab 12.7.
When you enable [Elastic Stack](../../clusters/integrations.md#elastic-stack-cluster-integration) on your cluster,
you can search the content of your logs through a search bar. The search is passed
to Elasticsearch using the
[simple_query_string](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html)
Elasticsearch function, which supports the following operators:
| Operator | Description |
|----------------------------|-------------------------------------------------------------|
| `\|` | An `OR` operation. |
| `-` | Negates a single token. |
| `+` | An `AND` operation. |
| `"` | Wraps a number of tokens to signify a phrase for searching. |
| `*` (at the end of a term) | A prefix query. |
| `(` and `)` | Precedence. |
| `~N` (after a word) | Edit distance (fuzziness). |
| `~N` (after a phrase) | Slop amount. |

View File

@ -9,11 +9,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
You can automatically trigger builds in Atlassian Bamboo when you push changes
to your project in GitLab.
When this integration is configured, merge requests also display the following information:
- A CI/CD status that shows if the build is pending, failed, or has completed successfully.
- A link to the Bamboo build page for more information.
Bamboo doesn't provide the same features as a traditional build system when
accepting webhooks and commit data. You must configure a Bamboo
build plan before you configure the integration in GitLab.
@ -66,6 +61,65 @@ for example `PROJ-PLAN`.
The build key is included in the browser URL when you view a plan in
Bamboo. For example, `https://bamboo.example.com/browse/PROJ-PLAN`.
## Update Bamboo build status in GitLab
You can use a script that uses the [commit status API](../../../api/commits.md#post-the-build-status-to-a-commit)
and Bamboo build variables to:
- Update the commit with the build status.
- Add the Bamboo build plan URL as the commit's `target_url`.
For example:
1. Create an [access token](../../../api/index.md#personalprojectgroup-access-tokens) in GitLab with `:api` permissions.
1. Save the token as a `$GITLAB_TOKEN` variable in Bamboo.
1. Add the following script as a final task to the Bamboo plan's jobs:
```shell
#!/bin/bash
# Script to update CI status on GitLab.
# Add this script as final inline script task in a Bamboo job.
#
# General documentation: https://docs.gitlab.com/ee/user/project/integrations/bamboo.html
# Fix inspired from https://gitlab.com/gitlab-org/gitlab/-/issues/34744
# Stop at first error
set -e
# Access token. Set this as a CI variable in Bamboo.
#GITLAB_TOKEN=
# Status
cistatus="failed"
if [ "${bamboo_buildFailed}" = "false" ]; then
cistatus="success"
fi
repo_url="${bamboo_planRepository_repositoryUrl}"
# Check if we use SSH or HTTPS
protocol=${repo_url::4}
if [ "$protocol" == "git@" ]; then
repo=${repo_url:${#protocol}};
gitlab_url=${repo%%:*};
else
protocol="https://"
repo=${repo_url:${#protocol}};
gitlab_url=${repo%%/*};
fi
start=$((${#gitlab_url} + 1)) # +1 for the / (https) or : (ssh)
end=$((${#repo} - $start -4)) # -4 for the .git
repo=${repo:$start:$end}
repo=$(echo "$repo" | sed "s/\//%2F/g")
# Send request
url="https://${gitlab_url}/api/v4/projects/${repo}/statuses/${bamboo_planRepository_revision}?state=${cistatus}&target_url=${bamboo_buildResultsUrl}"
echo "Sending request to $url"
curl --fail --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" "$url"
```
## Troubleshooting
### Builds not triggered

View File

@ -1,97 +1,11 @@
---
stage: Verify
group: Pipeline Insights
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/#assignments
redirect_to: '../../../ci/testing/fail_fast_testing.md'
remove_date: '2022-08-31'
---
# Fail Fast Testing **(PREMIUM)**
This document was moved to [another location](../../../ci/testing/fail_fast_testing.md).
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198550) in GitLab 13.1.
For applications that use RSpec for running tests, we've introduced the `Verify/Failfast`
[template to run subsets of your test suite](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Verify/FailFast.gitlab-ci.yml),
based on the changes in your merge request.
The template uses the [test_file_finder (`tff`) gem](https://gitlab.com/gitlab-org/ci-cd/test_file_finder/)
that accepts a list of files as input, and returns a list of spec (test) files
that it believes to be relevant to the input files.
`tff` is designed for Ruby on Rails projects, so the `Verify/FailFast` template is
configured to run when changes to Ruby files are detected. By default, it runs in
the [`.pre` stage](../../../ci/yaml/index.md#stage-pre) of a GitLab CI/CD pipeline,
before all other stages.
## Example use case
Fail fast testing is useful when adding new functionality to a project and adding
new automated tests.
Your project could have hundreds of thousands of tests that take a long time to complete.
You may be confident that a new test will pass, but you have to wait for all the tests
to complete to verify it. This could take an hour or more, even when using parallelization.
Fail fast testing gives you a faster feedback loop from the pipeline. It lets you
know quickly that the new tests are passing and the new functionality did not break
other tests.
## Requirements
This template requires:
- A project built in Rails that uses RSpec for testing.
- CI/CD configured to:
- Use a Docker image with Ruby available.
- Use [Merge request pipelines](../../../ci/pipelines/merge_request_pipelines.md#prerequisites)
- [Merged results pipelines](../../../ci/pipelines/merged_results_pipelines.md#enable-merged-results-pipelines)
enabled in the project settings.
- A Docker image with Ruby available. The template uses `image: ruby:2.6` by default, but you [can override](../../../ci/yaml/includes.md#override-included-configuration-values) this.
## Configuring Fast RSpec Failure
We use the following plain RSpec configuration as a starting point. It installs all the
project gems and executes `rspec`, on merge request pipelines only.
```yaml
rspec-complete:
stage: test
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- bundle install
- bundle exec rspec
```
To run the most relevant specs first instead of the whole suite, [`include`](../../../ci/yaml/index.md#include)
the template by adding the following to your CI/CD configuration:
```yaml
include:
- template: Verify/FailFast.gitlab-ci.yml
```
To customize the job, specific options may be set to override the template. For example, to override the default Docker image:
```yaml
include:
- template: Verify/FailFast.gitlab-ci.yml
rspec-rails-modified-path-specs:
image: custom-docker-image-with-ruby
```
### Example test loads
For illustrative purposes, let's say our Rails app spec suite consists of 100 specs per model for ten models.
If no Ruby files are changed:
- `rspec-rails-modified-paths-specs` does not run any tests.
- `rspec-complete` runs the full suite of 1000 tests.
If one Ruby model is changed, for example `app/models/example.rb`, then `rspec-rails-modified-paths-specs`
runs the 100 tests for `example.rb`:
- If all of these 100 tests pass, then the full `rspec-complete` suite of 1000 tests is allowed to run.
- If any of these 100 tests fail, they fail quickly, and `rspec-complete` does not run any tests.
The final case saves resources and time as the full 1000 test suite does not run.
<!-- This redirect file can be deleted after <2022-09-22>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -1,201 +1,11 @@
---
stage: Verify
group: Pipeline Insights
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/#assignments
redirect_to: '../../../ci/testing/load_performance_testing.md'
remove_date: '2022-08-31'
---
# Load Performance Testing **(PREMIUM)**
This document was moved to [another location](../../../ci/testing/load_performance_testing.md).
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10683) in GitLab 13.2.
With Load Performance Testing, you can test the impact of any pending code changes
to your application's backend in [GitLab CI/CD](../../../ci/index.md).
GitLab uses [k6](https://k6.io/), a free and open source
tool, for measuring the system performance of applications under
load.
Unlike [Browser Performance Testing](../../../ci/testing/browser_performance_testing.md), which is
used to measure how web sites perform in client browsers, Load Performance Testing
can be used to perform various types of [load tests](https://k6.io/docs/#use-cases)
against application endpoints such as APIs, Web Controllers, and so on.
This can be used to test how the backend or the server performs at scale.
For example, you can use Load Performance Testing to perform many concurrent
GET calls to a popular API endpoint in your application to see how it performs.
## How Load Performance Testing works
First, define a job in your `.gitlab-ci.yml` file that generates the
[Load Performance report artifact](../../../ci/yaml/artifacts_reports.md#artifactsreportsload_performance).
GitLab checks this report, compares key load performance metrics
between the source and target branches, and then shows the information in a merge request widget:
![Load Performance Widget](img/load_performance_testing.png)
Next, you need to configure the test environment and write the k6 test.
The key performance metrics that the merge request widget shows after the test completes are:
- Checks: The percentage pass rate of the [checks](https://k6.io/docs/using-k6/checks) configured in the k6 test.
- TTFB P90: The 90th percentile of how long it took to start receiving responses, aka the [Time to First Byte](https://en.wikipedia.org/wiki/Time_to_first_byte) (TTFB).
- TTFB P95: The 95th percentile for TTFB.
- RPS: The average requests per second (RPS) rate the test was able to achieve.
NOTE:
If the Load Performance report has no data to compare, such as when you add the
Load Performance job in your `.gitlab-ci.yml` for the very first time,
the Load Performance report widget doesn't display. It must have run at least
once on the target branch (`main`, for example), before it displays in a
merge request targeting that branch.
## Configure the Load Performance Testing job
Configuring your Load Performance Testing job can be broken down into several distinct parts:
- Determine the test parameters such as throughput, and so on.
- Set up the target test environment for load performance testing.
- Design and write the k6 test.
### Determine the test parameters
The first thing you need to do is determine the [type of load test](https://k6.io/docs/test-types/introduction)
you want to run, and how it will run (for example, the number of users, throughput, and so on).
Refer to the [k6 docs](https://k6.io/docs/), especially the [k6 testing guides](https://k6.io/docs/testing-guides),
for guidance on the above and more.
### Test Environment setup
A large part of the effort around load performance testing is to prepare the target test environment
for high loads. You should ensure it's able to handle the
[throughput](https://k6.io/blog/monthly-visits-concurrent-users) it will be tested with.
It's also typically required to have representative test data in the target environment
for the load performance test to use.
We strongly recommend [not running these tests against a production environment](https://k6.io/our-beliefs#load-test-in-a-pre-production-environment).
### Write the load performance test
After the environment is prepared, you can write the k6 test itself. k6 is a flexible
tool and can be used to run [many kinds of performance tests](https://k6.io/docs/test-types/introduction).
Refer to the [k6 documentation](https://k6.io/docs/) for detailed information on how to write tests.
### Configure the test in GitLab CI/CD
When your k6 test is ready, the next step is to configure the load performance
testing job in GitLab CI/CD. The easiest way to do this is to use the
[`Verify/Load-Performance-Testing.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Verify/Load-Performance-Testing.gitlab-ci.yml)
template that is included with GitLab.
NOTE:
For large scale k6 tests you need to ensure the GitLab Runner instance performing the actual
test is able to handle running the test. Refer to [k6's guidance](https://k6.io/docs/testing-guides/running-large-tests#hardware-considerations)
for spec details. The [default shared GitLab.com runners](../../../ci/runners/saas/linux_saas_runner.md)
likely have insufficient specs to handle most large k6 tests.
This template runs the
[k6 Docker container](https://hub.docker.com/r/loadimpact/k6/) in the job and provides several ways to customize the
job.
An example configuration workflow:
1. Set up GitLab Runner to run Docker containers, like the
[Docker-in-Docker workflow](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
1. Configure the default Load Performance Testing CI/CD job in your `.gitlab-ci.yml` file.
You need to include the template and configure it with CI/CD variables:
```yaml
include:
template: Verify/Load-Performance-Testing.gitlab-ci.yml
load_performance:
variables:
K6_TEST_FILE: <PATH TO K6 TEST FILE IN PROJECT>
```
The above example creates a `load_performance` job in your CI/CD pipeline that runs
the k6 test.
NOTE:
For Kubernetes setups a different template should be used: [`Jobs/Load-Performance-Testing.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml).
k6 has [various options](https://k6.io/docs/using-k6/options) to configure how it will run tests, such as what throughput (RPS) to run with,
how long the test should run, and so on. Almost all options can be configured in the test itself, but as
you can also pass command line options via the `K6_OPTIONS` variable.
For example, you can override the duration of the test with a CLI option:
```yaml
include:
template: Verify/Load-Performance-Testing.gitlab-ci.yml
load_performance:
variables:
K6_TEST_FILE: <PATH TO K6 TEST FILE IN PROJECT>
K6_OPTIONS: '--duration 30s'
```
GitLab only displays the key performance metrics in the MR widget if k6's results are saved
via [summary export](https://k6.io/docs/results-visualization/json#summary-export)
as a [Load Performance report artifact](../../../ci/yaml/artifacts_reports.md#artifactsreportsload_performance).
The latest Load Performance artifact available is always used, using the
summary values from the test.
If [GitLab Pages](../pages/index.md) is enabled, you can view the report directly in your browser.
### Load Performance testing in Review Apps
The CI/CD YAML configuration example above works for testing against static environments,
but it can be extended to work with [review apps](../../../ci/review_apps) or
[dynamic environments](../../../ci/environments) with a few extra steps.
The best approach is to capture the dynamic URL in a [`.env` file](https://docs.docker.com/compose/env-file/)
as a job artifact to be shared, then use a custom CI/CD variable we've provided named `K6_DOCKER_OPTIONS`
to configure the k6 Docker container to use the file. With this, k6 can then use any
environment variables from the `.env` file in scripts using standard JavaScript,
such as: ``http.get(`${__ENV.ENVIRONMENT_URL}`)``.
For example:
1. In the `review` job:
1. Capture the dynamic URL and save it into a `.env` file, for example, `echo "ENVIRONMENT_URL=$CI_ENVIRONMENT_URL" >> review.env`.
1. Set the `.env` file to be a [job artifact](../../../ci/pipelines/job_artifacts.md#job-artifacts).
1. In the `load_performance` job:
1. Set it to depend on the review job, so it inherits the environment file.
1. Set the `K6_DOCKER_OPTIONS` variable with the [Docker CLI option for environment files](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file), for example `--env-file review.env`.
1. Configure the k6 test script to use the environment variable in it's steps.
Your `.gitlab-ci.yml` file might be similar to:
```yaml
stages:
- deploy
- performance
include:
template: Verify/Load-Performance-Testing.gitlab-ci.yml
review:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_SLUG
url: http://$CI_ENVIRONMENT_SLUG.example.com
script:
- run_deploy_script
- echo "ENVIRONMENT_URL=$CI_ENVIRONMENT_URL" >> review.env
artifacts:
paths:
- review.env
rules:
- if: $CI_COMMIT_BRANCH # Modify to match your pipeline rules, or use `only/except` if needed.
load_performance:
dependencies:
- review
variables:
K6_DOCKER_OPTIONS: '--env-file review.env'
rules:
- if: $CI_COMMIT_BRANCH # Modify to match your pipeline rules, or use `only/except` if needed.
```
<!-- This redirect file can be deleted after <2022-09-22>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -1,441 +1,11 @@
---
stage: Verify
group: Pipeline Insights
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/#assignments
redirect_to: '../../../ci/testing/test_coverage_visualization.md'
remove_date: '2022-08-31'
---
# Test coverage visualization **(FREE)**
This document was moved to [another location](../../../ci/testing/test_coverage_visualization.md).
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/249811) in GitLab 13.5.
With the help of [GitLab CI/CD](../../../ci/index.md), you can collect the test
coverage information of your favorite testing or coverage-analysis tool, and visualize
this information inside the file diff view of your merge requests (MRs). This will allow you
to see which lines are covered by tests, and which lines still require coverage, before the
MR is merged.
![Test Coverage Visualization Diff View](img/test_coverage_visualization_v12_9.png)
## How test coverage visualization works
Collecting the coverage information is done via GitLab CI/CD's
[artifacts reports feature](../../../ci/yaml/index.md#artifactsreports).
You can specify one or more coverage reports to collect, including wildcard paths.
GitLab then takes the coverage information in all the files and combines it
together. Coverage files are parsed in a background job so there can be a delay
between pipeline completion and the visualization loading on the page.
For the coverage analysis to work, you have to provide a properly formatted
[Cobertura XML](https://cobertura.github.io/cobertura/) report to
[`artifacts:reports:coverage_report`](../../../ci/yaml/artifacts_reports.md#artifactsreportscoverage_report).
This format was originally developed for Java, but most coverage analysis frameworks
for other languages have plugins to add support for it, like:
- [simplecov-cobertura](https://rubygems.org/gems/simplecov-cobertura) (Ruby)
- [gocover-cobertura](https://github.com/boumenot/gocover-cobertura) (Golang)
Other coverage analysis frameworks support the format out of the box, for example:
- [Istanbul](https://istanbul.js.org/docs/advanced/alternative-reporters/#cobertura) (JavaScript)
- [Coverage.py](https://coverage.readthedocs.io/en/coverage-5.0.4/cmd.html#xml-reporting) (Python)
- [PHPUnit](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/master/src/textui.rst#command-line-options) (PHP)
Once configured, if you create a merge request that triggers a pipeline which collects
coverage reports, the coverage is shown in the diff view. This includes reports
from any job in any stage in the pipeline. The coverage displays for each line:
- `covered` (green): lines which have been checked at least once by tests
- `no test coverage` (orange): lines which are loaded but never executed
- no coverage information: lines which are non-instrumented or not loaded
Hovering over the coverage bar provides further information, such as the number
of times the line was checked by tests.
Uploading a test coverage report does not enable:
- [Test coverage results in merge requests](../../../ci/pipelines/settings.md#merge-request-test-coverage-results).
- [Code coverage history](../../../ci/pipelines/settings.md#view-code-coverage-history).
You must configure these separately.
### Limits
A limit of 100 `<source>` nodes for Cobertura format XML files applies. If your Cobertura report exceeds
100 nodes, there can be mismatches or no matches in the merge request diff view.
A single Cobertura XML file can be no more than 10MiB. For large projects, split the Cobertura XML into
smaller files. See [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/328772) for more details.
When submitting many files, it can take a few minutes for coverage to show on a merge request.
The visualization only displays after the pipeline is complete. If the pipeline has
a [blocking manual job](../../../ci/jobs/job_control.md#types-of-manual-jobs), the
pipeline waits for the manual job before continuing and is not considered complete.
The visualization cannot be displayed if the blocking manual job did not run.
### Artifact expiration
By default, the [pipeline artifact](../../../ci/pipelines/pipeline_artifacts.md#storage) used
to draw the visualization on the merge request expires **one week** after creation.
### Coverage report from child pipeline
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/363301) in GitLab 15.1 [with a flag](../../../administration/feature_flags.md). Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `ci_child_pipeline_coverage_reports`.
On GitLab.com, this feature is not available.
The feature is not ready for production use.
If the test coverage is created in jobs that are in a child pipeline, the parent pipeline must use
`strategy: depend`.
```yaml
child_test_pipeline:
trigger:
include:
- local: path/to/child_pipeline.yml
- template: Security/SAST.gitlab-ci.yml
strategy: depend
```
### Automatic class path correction
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217664) in GitLab 13.8.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/284822) in GitLab 13.9.
The coverage report properly matches changed files only if the `filename` of a `class` element
contains the full path relative to the project root. However, in some coverage analysis frameworks,
the generated Cobertura XML has the `filename` path relative to the class package directory instead.
To make an intelligent guess on the project root relative `class` path, the Cobertura XML parser
attempts to build the full path by:
- Extracting a portion of the `source` paths from the `sources` element and combining them with the
class `filename` path.
- Checking if the candidate path exists in the project.
- Using the first candidate that matches as the class full path.
#### Path correction example
As an example, a project with:
- A full path of `test-org/test-project`.
- The following files relative to the project root:
```shell
Auth/User.cs
Lib/Utils/User.cs
src/main/java
```
In the:
- Cobertura XML, the `filename` attribute in the `class` element assumes the value is a relative
path to the project's root:
```xml
<class name="packet.name" filename="src/main/java" line-rate="0.0" branch-rate="0.0" complexity="5">
```
- `sources` from Cobertura XML, the following paths in the format
`<CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/...`:
```xml
<sources>
<source>/builds/test-org/test-project/Auth</source>
<source>/builds/test-org/test-project/Lib/Utils</source>
</sources>
```
The parser:
- Extracts `Auth` and `Lib/Utils` from the `sources` and uses these to determine the `class` path
relative to the project root.
- Combines these extracted `sources` and the class filename. For example, if there is a `class`
element with the `filename` value of `User.cs`, the parser takes the first candidate path that
matches, which is `Auth/User.cs`.
- For each `class` element, attempts to look for a match for each extracted `source` path up to
100 iterations. If it reaches this limit without finding a matching path in the file tree, the
class is not included in the final coverage report.
NOTE:
Automatic class path correction only works on `source` paths in the format `<CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/...`.
The `source` is ignored if the path does not follow this pattern. The parser assumes that the
`filename` of a `class` element contains the full path relative to the project root.
## Example test coverage configurations
This section provides test coverage configuration examples for different programming languages. You can also see a working example in
the [`coverage-report`](https://gitlab.com/gitlab-org/ci-sample-projects/coverage-report/) demonstration project.
### JavaScript example
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example uses [Mocha](https://mochajs.org/)
JavaScript testing and [nyc](https://github.com/istanbuljs/nyc) coverage-tooling to
generate the coverage artifact:
```yaml
test:
script:
- npm install
- npx nyc --reporter cobertura mocha
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
```
### Java and Kotlin examples
#### Maven example
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Java or Kotlin uses [Maven](https://maven.apache.org/)
to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to
generate the coverage artifact.
You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image.
GitLab expects the artifact in the Cobertura format, so you have to execute a few
scripts before uploading it. The `test-jdk11` job tests the code and generates an
XML artifact. The `coverage-jdk-11` job converts the artifact into a Cobertura report:
```yaml
test-jdk11:
stage: test
image: maven:3.6.3-jdk-11
script:
- mvn $MAVEN_CLI_OPTS clean org.jacoco:jacoco-maven-plugin:prepare-agent test jacoco:report
artifacts:
paths:
- target/site/jacoco/jacoco.xml
coverage-jdk11:
# Must be in a stage later than test-jdk11's stage.
# The `visualize` stage does not exist by default.
# Please define it first, or choose an existing stage like `deploy`.
stage: visualize
image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
script:
# convert report from jacoco to cobertura, using relative project path
- python /opt/cover2cover.py target/site/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > target/site/cobertura.xml
needs: ["test-jdk11"]
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: target/site/cobertura.xml
```
#### Gradle example
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Java or Kotlin uses [Gradle](https://gradle.org/)
to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to
generate the coverage artifact.
You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image.
GitLab expects the artifact in the Cobertura format, so you have to execute a few
scripts before uploading it. The `test-jdk11` job tests the code and generates an
XML artifact. The `coverage-jdk-11` job converts the artifact into a Cobertura report:
```yaml
test-jdk11:
stage: test
image: gradle:6.6.1-jdk11
script:
- 'gradle test jacocoTestReport' # jacoco must be configured to create an xml report
artifacts:
paths:
- build/jacoco/jacoco.xml
coverage-jdk11:
# Must be in a stage later than test-jdk11's stage.
# The `visualize` stage does not exist by default.
# Please define it first, or chose an existing stage like `deploy`.
stage: visualize
image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
script:
# convert report from jacoco to cobertura, using relative project path
- python /opt/cover2cover.py build/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > build/cobertura.xml
needs: ["test-jdk11"]
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: build/cobertura.xml
```
### Python example
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Python uses [pytest-cov](https://pytest-cov.readthedocs.io/) to collect test coverage data and [coverage.py](https://coverage.readthedocs.io/) to convert the report to use full relative paths.
The information isn't displayed without the conversion.
This example assumes that the code for your package is in `src/` and your tests are in `tests.py`:
```yaml
run tests:
stage: test
image: python:3
script:
- pip install pytest pytest-cov
- coverage run -m pytest
- coverage report
- coverage xml
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
```
### PHP example
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for PHP uses [PHPUnit](https://phpunit.readthedocs.io/)
to collect test coverage data and generate the report.
With a minimal [`phpunit.xml`](https://phpunit.readthedocs.io/en/9.5/configuration.html) file (you may reference
[this example repository](https://gitlab.com/yookoala/code-coverage-visualization-with-php/)), you can run the test and
generate the `coverage.xml`:
```yaml
run tests:
stage: test
image: php:latest
variables:
XDEBUG_MODE: coverage
before_script:
- apt-get update && apt-get -yq install git unzip zip libzip-dev zlib1g-dev
- docker-php-ext-install zip
- pecl install xdebug && docker-php-ext-enable xdebug
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php --install-dir=/usr/local/bin --filename=composer
- composer install
- composer require --dev phpunit/phpunit phpunit/php-code-coverage
script:
- php ./vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.cobertura.xml
```
[Codeception](https://codeception.com/), through PHPUnit, also supports generating Cobertura report with
[`run`](https://codeception.com/docs/reference/Commands#run). The path for the generated file
depends on the `--coverage-cobertura` option and [`paths`](https://codeception.com/docs/reference/Configuration#paths)
configuration for the [unit test suite](https://codeception.com/docs/05-UnitTests). Configure `.gitlab-ci.yml`
to find Cobertura in the appropriate path.
### C/C++ example
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for C/C++ with
`gcc` or `g++` as the compiler uses [`gcovr`](https://gcovr.com/en/stable/) to generate the coverage
output file in Cobertura XML format.
This example assumes:
- That the `Makefile` is created by `cmake` in the `build` directory,
within another job in a previous stage.
(If you use `automake` to generate the `Makefile`,
then you need to call `make check` instead of `make test`.)
- `cmake` (or `automake`) has set the compiler option `--coverage`.
```yaml
run tests:
stage: test
script:
- cd build
- make test
- gcovr --xml-pretty --exclude-unreachable-branches --print-summary -o coverage.xml --root ${CI_PROJECT_DIR}
coverage: /^\s*lines:\s*\d+.\d+\%/
artifacts:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
expire_in: 2 days
reports:
coverage_report:
coverage_format: cobertura
path: build/coverage.xml
```
### Go example
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Go uses:
- [`go test`](https://go.dev/doc/tutorial/add-a-test) to run tests.
- [`gocover-cobertura`](https://github.com/boumenot/gocover-cobertura) to convert Go's coverage profile into the Cobertura XML format.
This example assumes that [Go modules](https://go.dev/ref/mod)
are being used. Please note that the `-covermode count` option does not work with the `-race` flag.
If you want to generate code coverage while also using the `-race` flag, you must switch to
`-covermode atomic` which is slower than `-covermode count`. See [this blog post](https://go.dev/blog/cover)
for more details.
```yaml
run tests:
stage: test
image: golang:1.17
script:
- go install
- go test ./... -coverprofile=coverage.txt -covermode count
- go get github.com/boumenot/gocover-cobertura
- go run github.com/boumenot/gocover-cobertura < coverage.txt > coverage.xml
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
```
### Ruby example
The following [`.gitlab-ci.yml`](../../../ci/yaml/index.md) example for Ruby uses
- [`rspec`](https://rspec.info/) to run tests.
- [`simplecov`](https://github.com/simplecov-ruby/simplecov) and [`simplecov-cobertura`](https://github.com/dashingrocket/simplecov-cobertura)
to record the coverage profile and create a report in the Cobertura XML format.
This example assumes:
- That [`bundler`](https://bundler.io/) is being used for dependency management.
The `rspec`, `simplecov` and `simplecov-cobertura` gems have been added to your `Gemfile`.
- The `CoberturaFormatter` has been added to your `SimpleCov.formatters`
configuration within the `spec_helper.rb` file.
```yaml
run tests:
stage: test
image: ruby:3.1
script:
- bundle install
- bundle exec rspec
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/coverage.xml
```
## Troubleshooting
### Test coverage visualization not displayed
If the test coverage visualization is not displayed in the diff view, you can check
the coverage report itself and verify that:
- The file you are viewing in the diff view is mentioned in the coverage report.
- The `source` and `filename` nodes in the report follows the [expected structure](#automatic-class-path-correction)
to match the files in your repository.
Report artifacts are not downloadable by default. If you want the report to be downloadable
from the job details page, add your coverage report to the artifact `paths`:
```yaml
artifacts:
paths:
- coverage/cobertura-coverage.xml
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
```
<!-- This redirect file can be deleted after <2022-09-22>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -8,6 +8,7 @@ module API
expose :name, :entrypoint
expose :ports, using: Entities::Ci::JobRequest::Port
expose :pull_policy, if: ->(_) { ::Feature.enabled?(:ci_docker_image_pull_policy) }
expose :alias, :command
expose :variables
end

View File

@ -48,7 +48,7 @@ module Gitlab
{
name: @config[:name],
entrypoint: @config[:entrypoint],
ports: ports_value,
ports: (ports_value if ports_defined?),
pull_policy: (ci_docker_image_pull_policy_enabled? ? pull_policy_value : nil)
}.compact
else

View File

@ -15,11 +15,13 @@ module Gitlab
include ::Gitlab::Config::Entry::Attributable
include ::Gitlab::Config::Entry::Configurable
ALLOWED_KEYS = %i[name entrypoint command alias ports variables].freeze
ALLOWED_KEYS = %i[name entrypoint command alias ports variables pull_policy].freeze
LEGACY_ALLOWED_KEYS = %i[name entrypoint command alias ports variables].freeze
validations do
validates :config, hash_or_string: true
validates :config, allowed_keys: ALLOWED_KEYS
validates :config, allowed_keys: ALLOWED_KEYS, if: :ci_docker_image_pull_policy_enabled?
validates :config, allowed_keys: LEGACY_ALLOWED_KEYS, unless: :ci_docker_image_pull_policy_enabled?
validates :config, disallowed_keys: %i[ports], unless: :with_image_ports?
validates :name, type: String, presence: true
validates :entrypoint, array_of_strings: true, allow_nil: true
@ -32,11 +34,14 @@ module Gitlab
entry :ports, Entry::Ports,
description: 'Ports used to expose the service'
entry :pull_policy, Entry::PullPolicy,
description: 'Pull policy for the service'
entry :variables, ::Gitlab::Ci::Config::Entry::Variables,
description: 'Environment variables available for this service.',
inherit: false
attributes :ports
attributes :ports, :pull_policy, :variables
def alias
value[:alias]
@ -55,16 +60,25 @@ module Gitlab
end
def value
return { name: @config } if string?
return @config if hash?
{}
if string?
{ name: @config }
elsif hash?
@config.merge(
pull_policy: (pull_policy_value if ci_docker_image_pull_policy_enabled?)
).compact
else
{}
end
end
def with_image_ports?
opt(:with_image_ports)
end
def ci_docker_image_pull_policy_enabled?
::Feature.enabled?(:ci_docker_image_pull_policy)
end
def skip_config_hash_validation?
true
end

View File

@ -11,8 +11,15 @@ module Gitlab
end
end
class PipelinedDiffError < StandardError
def initialize(result_primary, result_secondary)
@result_primary = result_primary
@result_secondary = result_secondary
end
def message
'Pipelined command executed on both stores successfully but results differ between them.'
"Pipelined command executed on both stores successfully but results differ between them. " \
"Result from the primary: #{@result_primary.inspect}. " \
"Result from the secondary: #{@result_secondary.inspect}."
end
end
class MethodMissingError < StandardError
@ -246,10 +253,12 @@ module Gitlab
result_secondary = send_command(secondary_store, command_name, *args, **kwargs, &block)
# Pipelined commands return an array with all results. If they differ,
# log an error
if result_primary != result_secondary
log_error(PipelinedDiffError.new, command_name)
# Pipelined commands return an array with all results. If they differ, log an error
if result_primary && result_primary != result_secondary
error = PipelinedDiffError.new(result_primary, result_secondary)
error.set_backtrace(Thread.current.backtrace[1..]) # Manually set backtrace, since the error is not `raise`d
log_error(error, command_name)
increment_pipelined_command_error_count(command_name)
end

View File

@ -48,6 +48,10 @@ module Gitlab
def self.about_pricing_faq_url
"https://about.gitlab.com/pricing#faq"
end
def self.doc_url
'https://docs.gitlab.com'
end
end
end

View File

@ -135,7 +135,6 @@ module Gitlab
projects_creating_incidents: distinct_count(Issue.incident, :project_id),
projects_imported_from_github: count(Project.where(import_type: 'github')),
projects_with_repositories_enabled: count(ProjectFeature.where('repository_access_level > ?', ProjectFeature::DISABLED)),
projects_with_tracing_enabled: count(ProjectTracingSetting),
projects_with_error_tracking_enabled: count(::ErrorTracking::ProjectErrorTrackingSetting.where(enabled: true)),
projects_with_alerts_created: distinct_count(::AlertManagement::Alert, :project_id),
projects_with_enabled_alert_integrations: distinct_count(::AlertManagement::HttpIntegration.active, :project_id),
@ -558,7 +557,6 @@ module Gitlab
operations_dashboard_default_dashboard: count(::User.active.with_dashboard('operations').where(time_period),
start: minimum_id(User),
finish: maximum_id(User)),
projects_with_tracing_enabled: distinct_count(::Project.with_tracing_enabled.where(time_period), :creator_id),
projects_with_error_tracking_enabled: distinct_count(::Project.with_enabled_error_tracking.where(time_period), :creator_id),
projects_with_incidents: distinct_count(::Issue.incident.where(time_period), :project_id),
projects_with_alert_incidents: distinct_count(::Issue.incident.with_alert_management_alerts.where(time_period), :project_id),

View File

@ -2607,6 +2607,9 @@ msgstr ""
msgid "AdminSettings|Auto DevOps domain"
msgstr ""
msgid "AdminSettings|Automatically ban users who download more than a specified number of repositories in a given time."
msgstr ""
msgid "AdminSettings|CI/CD limits"
msgstr ""
@ -2679,6 +2682,9 @@ msgstr ""
msgid "AdminSettings|Feed token"
msgstr ""
msgid "AdminSettings|Git abuse rate limit"
msgstr ""
msgid "AdminSettings|I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end} (PDF)."
msgstr ""
@ -2706,6 +2712,24 @@ msgstr ""
msgid "AdminSettings|Limit the number of namespaces and projects that can be indexed."
msgstr ""
msgid "AdminSettings|Max number of repository downloads is not a number"
msgstr ""
msgid "AdminSettings|Max number of repository downloads must be greater than or equal to 0"
msgstr ""
msgid "AdminSettings|Max number of repository downloads must be less than or equal to 10000"
msgstr ""
msgid "AdminSettings|Max number of repository downloads within time period is not a number"
msgstr ""
msgid "AdminSettings|Max number of repository downloads within time period must be greater than or equal to 0"
msgstr ""
msgid "AdminSettings|Max number of repository downloads within time period must be less than or equal to 864000"
msgstr ""
msgid "AdminSettings|Maximum duration of a session for Git operations when 2FA is enabled."
msgstr ""
@ -2739,6 +2763,9 @@ msgstr ""
msgid "AdminSettings|No required pipeline"
msgstr ""
msgid "AdminSettings|Number of repositories"
msgstr ""
msgid "AdminSettings|Only enable search after installing the plugin, enabling indexing, and recreating the index."
msgstr ""
@ -2757,6 +2784,9 @@ msgstr ""
msgid "AdminSettings|Registration Features include:"
msgstr ""
msgid "AdminSettings|Reporting time period (seconds)"
msgstr ""
msgid "AdminSettings|Require users to prove ownership of custom domains"
msgstr ""
@ -2820,6 +2850,9 @@ msgstr ""
msgid "AdminSettings|The latest artifacts for all jobs in the most recent successful pipelines in each project are stored and do not expire."
msgstr ""
msgid "AdminSettings|The maximum number of unique repositories a user can download in the specified time period before they're banned."
msgstr ""
msgid "AdminSettings|The projects in this group can be selected as templates for new projects created on the instance. %{link_start}Learn more.%{link_end} "
msgstr ""
@ -8564,9 +8597,6 @@ msgstr ""
msgid "ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster."
msgstr ""
msgid "ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Elasticsearch for pod logs."
msgstr ""
msgid "ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics."
msgstr ""
@ -8651,9 +8681,6 @@ msgstr ""
msgid "ClusterIntegration|Elastic Kubernetes Service"
msgstr ""
msgid "ClusterIntegration|Enable Elastic Stack integration"
msgstr ""
msgid "ClusterIntegration|Enable Prometheus integration"
msgstr ""
@ -8840,7 +8867,7 @@ msgstr ""
msgid "ClusterIntegration|The certificate-based method to connect clusters to GitLab was %{linkStart}deprecated%{linkEnd} in GitLab 14.5."
msgstr ""
msgid "ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals."
msgid "ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, and Web terminals."
msgstr ""
msgid "ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid."
@ -13676,6 +13703,9 @@ msgstr ""
msgid "Edit %{name}"
msgstr ""
msgid "Edit %{profileType} profile"
msgstr ""
msgid "Edit Comment"
msgstr ""
@ -13703,9 +13733,6 @@ msgstr ""
msgid "Edit Pipeline Schedule"
msgstr ""
msgid "Edit Profile"
msgstr ""
msgid "Edit Release"
msgstr ""
@ -13997,9 +14024,6 @@ msgstr ""
msgid "Embed"
msgstr ""
msgid "Embed an image of your existing Jaeger server in GitLab."
msgstr ""
msgid "Empty file"
msgstr ""
@ -21718,9 +21742,6 @@ msgstr ""
msgid "Iteration|cannot be more than 500 years in the future"
msgstr ""
msgid "Jaeger URL"
msgstr ""
msgid "Jan"
msgstr ""
@ -22632,9 +22653,6 @@ msgstr ""
msgid "Learn more"
msgstr ""
msgid "Learn more about %{link_start_tag}Jaeger configuration%{link_end_tag}."
msgstr ""
msgid "Learn more about %{username}"
msgstr ""

View File

@ -53,7 +53,7 @@
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "2.21.0",
"@gitlab/ui": "41.10.0",
"@gitlab/ui": "42.7.0",
"@gitlab/visual-review-tools": "1.7.3",
"@rails/actioncable": "6.1.4-7",
"@rails/ujs": "6.1.4-7",

View File

@ -309,7 +309,7 @@ function retry_failed_rspec_examples() {
rspec_run_status=$?
# Merge the JUnit report from retry into the first-try report
junit_merge "${JUNIT_RETRY_FILE}" "${JUNIT_RESULT_FILE}"
junit_merge "${JUNIT_RETRY_FILE}" "${JUNIT_RESULT_FILE}" --update-only
exit $rspec_run_status
}

View File

@ -38,11 +38,12 @@ function bundle_install_script() {
exit 1;
fi;
gem install bundler --no-document --conservative --version 2.3.15
gem --version
bundle --version
gem install bundler --no-document --conservative --version 2.3.15
test -d jh && bundle config set --local gemfile 'jh/Gemfile'
bundle config set path "$(pwd)/vendor"
bundle config set clean 'true'
test -d jh && bundle config set --local gemfile 'jh/Gemfile'
echo "${BUNDLE_WITHOUT}"
bundle config

View File

@ -437,108 +437,6 @@ RSpec.describe Projects::Settings::OperationsController do
end
end
context 'tracing integration' do
describe 'GET #show' do
context 'with existing setting' do
let_it_be(:setting) do
create(:project_tracing_setting, project: project)
end
it 'loads existing setting' do
get :show, params: project_params(project)
expect(controller.helpers.tracing_setting).to eq(setting)
end
end
context 'without an existing setting' do
it 'builds a new setting' do
get :show, params: project_params(project)
expect(controller.helpers.tracing_setting).to be_new_record
end
end
end
describe 'PATCH #update' do
let_it_be(:external_url) { 'https://gitlab.com' }
let(:params) do
{
tracing_setting_attributes: {
external_url: external_url
}
}
end
it_behaves_like 'PATCHable'
describe 'gitlab tracking', :snowplow do
shared_examples 'event tracking' do
it 'tracks an event' do
expect_snowplow_event(
category: 'project:operations:tracing',
action: 'external_url_populated',
user: user,
project: project,
namespace: project.namespace
)
end
end
shared_examples 'no event tracking' do
it 'does not track an event' do
expect_no_snowplow_event
end
end
before do
make_request
end
subject(:make_request) do
patch :update, params: project_params(project, params), format: :json
end
context 'without existing setting' do
context 'when creating a new setting' do
it_behaves_like 'event tracking'
end
context 'with invalid external_url' do
let_it_be(:external_url) { nil }
it_behaves_like 'no event tracking'
end
end
context 'with existing setting' do
let_it_be(:existing_setting) do
create(:project_tracing_setting,
project: project,
external_url: external_url)
end
context 'when changing external_url' do
let_it_be(:external_url) { 'https://example.com' }
it_behaves_like 'no event tracking'
end
context 'with unchanged external_url' do
it_behaves_like 'no event tracking'
end
context 'with invalid external_url' do
let_it_be(:external_url) { nil }
it_behaves_like 'no event tracking'
end
end
end
end
end
private
def project_params(project, params = {})

View File

@ -0,0 +1,51 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe API::Entities::Ci::JobRequest::Service do
let(:ports) { [{ number: 80, protocol: 'http', name: 'name' }]}
let(:service) do
instance_double(
::Gitlab::Ci::Build::Image,
name: 'image_name',
entrypoint: ['foo'],
ports: ports,
pull_policy: ['if-not-present'],
alias: 'alias',
command: 'command',
variables: [{ key: 'key', value: 'value' }]
)
end
let(:entity) { described_class.new(service) }
subject(:result) { entity.as_json }
it 'exposes attributes' do
expect(result).to eq(
name: 'image_name',
entrypoint: ['foo'],
ports: ports,
pull_policy: ['if-not-present'],
alias: 'alias',
command: 'command',
variables: [{ key: 'key', value: 'value' }]
)
end
context 'when the ports param is nil' do
let(:ports) { nil }
it 'does not return the ports' do
expect(subject[:ports]).to be_nil
end
end
context 'when the FF ci_docker_image_pull_policy is disabled' do
before do
stub_feature_flags(ci_docker_image_pull_policy: false)
end
it { is_expected.not_to have_key(:pull_policy) }
end
end

View File

@ -98,9 +98,11 @@ RSpec.describe Gitlab::Ci::Build::Image do
let(:service_entrypoint) { '/bin/sh' }
let(:service_alias) { 'db' }
let(:service_command) { 'sleep 30' }
let(:pull_policy) { %w[always if-not-present] }
let(:job) do
create(:ci_build, options: { services: [{ name: service_image_name, entrypoint: service_entrypoint,
alias: service_alias, command: service_command, ports: [80] }] })
alias: service_alias, command: service_command, ports: [80],
pull_policy: pull_policy }] })
end
it 'fabricates an non-empty array of objects' do
@ -114,6 +116,7 @@ RSpec.describe Gitlab::Ci::Build::Image do
expect(subject.first.entrypoint).to eq(service_entrypoint)
expect(subject.first.alias).to eq(service_alias)
expect(subject.first.command).to eq(service_command)
expect(subject.first.pull_policy).to eq(pull_policy)
port = subject.first.ports.first
expect(port.number).to eq 80

View File

@ -9,6 +9,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Image do
before do
stub_feature_flags(ci_docker_image_pull_policy: true)
entry.compose!
end
let(:entry) { described_class.new(config) }
@ -129,19 +131,16 @@ RSpec.describe Gitlab::Ci::Config::Entry::Image do
describe '#valid?' do
it 'is valid' do
entry.compose!
expect(entry).to be_valid
end
context 'when the feature flag ci_docker_image_pull_policy is disabled' do
before do
stub_feature_flags(ci_docker_image_pull_policy: false)
entry.compose!
end
it 'is not valid' do
entry.compose!
expect(entry).not_to be_valid
expect(entry.errors).to include('image config contains unknown keys: pull_policy')
end
@ -150,8 +149,6 @@ RSpec.describe Gitlab::Ci::Config::Entry::Image do
describe '#value' do
it "returns value" do
entry.compose!
expect(entry.value).to eq(
name: 'image:1.0',
pull_policy: ['if-not-present']
@ -161,11 +158,10 @@ RSpec.describe Gitlab::Ci::Config::Entry::Image do
context 'when the feature flag ci_docker_image_pull_policy is disabled' do
before do
stub_feature_flags(ci_docker_image_pull_policy: false)
entry.compose!
end
it 'is not valid' do
entry.compose!
expect(entry.value).to eq(
name: 'image:1.0'
)

View File

@ -1,14 +1,19 @@
# frozen_string_literal: true
require 'spec_helper'
require 'fast_spec_helper'
require 'support/helpers/stubbed_feature'
require 'support/helpers/stub_feature_flags'
RSpec.describe Gitlab::Ci::Config::Entry::Service do
let(:entry) { described_class.new(config) }
include StubFeatureFlags
before do
stub_feature_flags(ci_docker_image_pull_policy: true)
entry.compose!
end
subject(:entry) { described_class.new(config) }
context 'when configuration is a string' do
let(:config) { 'postgresql:9.5' }
@ -90,6 +95,12 @@ RSpec.describe Gitlab::Ci::Config::Entry::Service do
end
end
describe '#pull_policy' do
it "returns nil" do
expect(entry.pull_policy).to be_nil
end
end
context 'when configuration has ports' do
let(:ports) { [{ number: 80, protocol: 'http', name: 'foobar' }] }
let(:config) do
@ -134,6 +145,49 @@ RSpec.describe Gitlab::Ci::Config::Entry::Service do
end
end
end
context 'when configuration has pull_policy' do
let(:config) { { name: 'postgresql:9.5', pull_policy: 'if-not-present' } }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
context 'when the feature flag ci_docker_image_pull_policy is disabled' do
before do
stub_feature_flags(ci_docker_image_pull_policy: false)
entry.compose!
end
it 'is not valid' do
expect(entry).not_to be_valid
expect(entry.errors).to include('service config contains unknown keys: pull_policy')
end
end
end
describe '#value' do
it "returns value" do
expect(entry.value).to eq(
name: 'postgresql:9.5',
pull_policy: ['if-not-present']
)
end
context 'when the feature flag ci_docker_image_pull_policy is disabled' do
before do
stub_feature_flags(ci_docker_image_pull_policy: false)
end
it 'is not valid' do
expect(entry.value).to eq(
name: 'postgresql:9.5'
)
end
end
end
end
end
context 'when entry value is not correct' do

View File

@ -980,7 +980,7 @@ module Gitlab
it { is_expected.to be_valid }
it "returns image and service when defined" do
it "returns with image" do
expect(processor.stage_builds_attributes("test")).to contain_exactly({
stage: "test",
stage_idx: 2,
@ -1010,6 +1010,51 @@ module Gitlab
end
end
end
context 'when a service has pull_policy' do
let(:config) do
<<~YAML
services:
- name: postgres:11.9
pull_policy: if-not-present
test:
script: exit 0
YAML
end
it { is_expected.to be_valid }
it "returns with service" do
expect(processor.stage_builds_attributes("test")).to contain_exactly({
stage: "test",
stage_idx: 2,
name: "test",
only: { refs: %w[branches tags] },
options: {
script: ["exit 0"],
services: [{ name: "postgres:11.9", pull_policy: ["if-not-present"] }]
},
allow_failure: false,
when: "on_success",
job_variables: [],
root_variables_inheritance: true,
scheduling_type: :stage
})
end
context 'when the feature flag ci_docker_image_pull_policy is disabled' do
before do
stub_feature_flags(ci_docker_image_pull_policy: false)
end
it { is_expected.not_to be_valid }
it "returns no job" do
expect(processor.jobs).to eq({})
end
end
end
end
describe 'Variables' do

View File

@ -507,7 +507,7 @@ RSpec.describe Gitlab::Redis::MultiStore do
secondary_store.flushdb
end
describe "command execution in a transaction" do
describe "command execution in a pipelined command" do
let(:counter) { Gitlab::Metrics::NullMetric.instance }
before do
@ -557,7 +557,15 @@ RSpec.describe Gitlab::Redis::MultiStore do
include_examples 'verify that store contains values', :secondary_store
end
describe 'return values from a transaction' do
describe 'return values from a pipelined command' do
RSpec::Matchers.define :pipeline_diff_error_with_stacktrace do |message|
match do |object|
expect(object).to be_a(Gitlab::Redis::MultiStore::PipelinedDiffError)
expect(object.backtrace).not_to be_nil
expect(object.message).to eq(message)
end
end
subject do
multi_store.send(name) do |redis|
redis.get(key1)
@ -585,7 +593,10 @@ RSpec.describe Gitlab::Redis::MultiStore do
it 'returns the value from the secondary store, logging an error' do
expect(Gitlab::ErrorTracking).to receive(:log_exception).with(
an_instance_of(Gitlab::Redis::MultiStore::PipelinedDiffError),
pipeline_diff_error_with_stacktrace(
'Pipelined command executed on both stores successfully but results differ between them. ' \
"Result from the primary: [#{value1.inspect}]. Result from the secondary: [#{value2.inspect}]."
),
hash_including(command_name: name, instance_name: instance_name)
).and_call_original
expect(counter).to receive(:increment).with(command: name, instance_name: instance_name)
@ -601,7 +612,10 @@ RSpec.describe Gitlab::Redis::MultiStore do
it 'returns the value from the secondary store, logging an error' do
expect(Gitlab::ErrorTracking).to receive(:log_exception).with(
an_instance_of(Gitlab::Redis::MultiStore::PipelinedDiffError),
pipeline_diff_error_with_stacktrace(
'Pipelined command executed on both stores successfully but results differ between them. ' \
"Result from the primary: [nil]. Result from the secondary: [#{value2.inspect}]."
),
hash_including(command_name: name, instance_name: instance_name)
)
expect(counter).to receive(:increment).with(command: name, instance_name: instance_name)

View File

@ -347,7 +347,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
cluster = create(:cluster, user: user)
project = create(:project, creator: user)
create(:clusters_integrations_prometheus, cluster: cluster)
create(:project_tracing_setting)
create(:project_error_tracking_setting)
create(:incident)
create(:incident, alert_management_alert: create(:alert_management_alert))
@ -358,7 +357,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
clusters: 2,
clusters_integrations_prometheus: 2,
operations_dashboard_default_dashboard: 2,
projects_with_tracing_enabled: 2,
projects_with_error_tracking_enabled: 2,
projects_with_incidents: 4,
projects_with_alert_incidents: 2,
@ -370,7 +368,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
clusters: 1,
clusters_integrations_prometheus: 1,
operations_dashboard_default_dashboard: 1,
projects_with_tracing_enabled: 1,
projects_with_error_tracking_enabled: 1,
projects_with_incidents: 2,
projects_with_alert_incidents: 1
@ -535,7 +532,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(count_data[:groups_inheriting_slack_active]).to eq(1)
expect(count_data[:projects_with_repositories_enabled]).to eq(3)
expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
expect(count_data[:projects_with_tracing_enabled]).to eq(1)
expect(count_data[:projects_with_enabled_alert_integrations]).to eq(1)
expect(count_data[:projects_with_terraform_reports]).to eq(2)
expect(count_data[:projects_with_terraform_states]).to eq(2)

View File

@ -38,10 +38,24 @@ RSpec.describe API::AwardEmoji do
end
end
shared_examples 'unauthenticated request to public awardable' do
before do
project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
it 'returns the awarded emoji' do
get api(request_path)
expect(response).to have_gitlab_http_status(:ok)
end
end
describe "GET /projects/:id/awardable/:awardable_id/award_emoji" do
context 'on an issue' do
let(:request_path) { "/projects/#{project.id}/issues/#{issue.iid}/award_emoji" }
it "returns an array of award_emoji" do
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user)
get api(request_path, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
@ -70,6 +84,9 @@ RSpec.describe API::AwardEmoji do
expect(response).to have_gitlab_http_status(:not_found)
end
it_behaves_like 'unauthenticated request to public awardable'
it_behaves_like 'request with insufficient permissions', :get
end
context 'on a merge request' do
@ -95,60 +112,30 @@ RSpec.describe API::AwardEmoji do
expect(json_response.first['name']).to eq(award.name)
end
end
context 'when unauthenticated and project is public' do
before do
project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
it 'returns the awarded emoji' do
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji")
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(award_emoji.name)
end
end
it_behaves_like 'request with insufficient permissions', :get do
let(:request_path) { "/projects/#{project.id}/issues/#{issue.iid}/award_emoji" }
end
end
describe 'GET /projects/:id/awardable/:awardable_id/notes/:note_id/award_emoji' do
let!(:rocket) { create(:award_emoji, awardable: note, name: 'rocket') }
let!(:rocket) { create(:award_emoji, awardable: note, name: 'rocket') }
let(:request_path) { "/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji" }
it 'returns an array of award emoji' do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user)
get api(request_path, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(rocket.name)
end
context 'when unauthenticated and project is public' do
before do
project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
it 'returns the awarded emoji' do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji")
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(rocket.name)
end
end
it_behaves_like 'request with insufficient permissions', :get do
let(:request_path) { "/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji" }
end
it_behaves_like 'unauthenticated request to public awardable'
it_behaves_like 'request with insufficient permissions', :get
end
describe "GET /projects/:id/awardable/:awardable_id/award_emoji/:award_id" do
context 'on an issue' do
let(:request_path) { "/projects/#{project.id}/issues/#{issue.iid}/award_emoji/#{award_emoji.id}" }
it "returns the award emoji" do
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/#{award_emoji.id}", user)
get api(request_path, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(award_emoji.name)
@ -161,6 +148,9 @@ RSpec.describe API::AwardEmoji do
expect(response).to have_gitlab_http_status(:not_found)
end
it_behaves_like 'unauthenticated request to public awardable'
it_behaves_like 'request with insufficient permissions', :get
end
context 'on a merge request' do
@ -187,55 +177,22 @@ RSpec.describe API::AwardEmoji do
expect(json_response['awardable_type']).to eq("Snippet")
end
end
context 'when unauthenticated and project is public' do
before do
project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
it 'returns the awarded emoji' do
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/#{award_emoji.id}", user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(award_emoji.name)
expect(json_response['awardable_id']).to eq(issue.id)
expect(json_response['awardable_type']).to eq("Issue")
end
end
it_behaves_like 'request with insufficient permissions', :get do
let(:request_path) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/award_emoji/#{downvote.id}" }
end
end
describe 'GET /projects/:id/awardable/:awardable_id/notes/:note_id/award_emoji/:award_id' do
let!(:rocket) { create(:award_emoji, awardable: note, name: 'rocket') }
let!(:rocket) { create(:award_emoji, awardable: note, name: 'rocket') }
let(:request_path) { "/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji/#{rocket.id}" }
it 'returns an award emoji' do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji/#{rocket.id}", user)
get api(request_path, user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).not_to be_an Array
expect(json_response['name']).to eq(rocket.name)
end
context 'when unauthenticated and project is public' do
before do
project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
it 'returns the awarded emoji' do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji/#{rocket.id}")
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).not_to be_an Array
expect(json_response['name']).to eq(rocket.name)
end
end
it_behaves_like 'request with insufficient permissions', :get do
let(:request_path) { "/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji/#{rocket.id}" }
end
it_behaves_like 'unauthenticated request to public awardable'
it_behaves_like 'request with insufficient permissions', :get
end
describe "POST /projects/:id/awardable/:awardable_id/award_emoji" do
@ -264,12 +221,6 @@ RSpec.describe API::AwardEmoji do
expect(response).to have_gitlab_http_status(:bad_request)
end
it "returns a 404 if the user is not authenticated" do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji"), params: { name: 'thumbsup' }
expect(response).to have_gitlab_http_status(:not_found)
end
it "normalizes +1 as thumbsup award" do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), params: { name: '+1' }

View File

@ -216,13 +216,17 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
expect(json_response['token']).to eq(job.token)
expect(json_response['job_info']).to eq(expected_job_info)
expect(json_response['git_info']).to eq(expected_git_info)
expect(json_response['image']).to eq({ 'name' => 'image:1.0', 'entrypoint' => '/bin/sh', 'ports' => [], 'pull_policy' => nil })
expect(json_response['services']).to eq([{ 'name' => 'postgres', 'entrypoint' => nil,
'alias' => nil, 'command' => nil, 'ports' => [], 'variables' => nil },
{ 'name' => 'docker:stable-dind', 'entrypoint' => '/bin/sh',
'alias' => 'docker', 'command' => 'sleep 30', 'ports' => [], 'variables' => [] },
{ 'name' => 'mysql:latest', 'entrypoint' => nil,
'alias' => nil, 'command' => nil, 'ports' => [], 'variables' => [{ 'key' => 'MYSQL_ROOT_PASSWORD', 'value' => 'root123.' }] }])
expect(json_response['image']).to eq(
{ 'name' => 'image:1.0', 'entrypoint' => '/bin/sh', 'ports' => [], 'pull_policy' => nil }
)
expect(json_response['services']).to eq([
{ 'name' => 'postgres', 'entrypoint' => nil, 'alias' => nil, 'command' => nil, 'ports' => [],
'variables' => nil, 'pull_policy' => nil },
{ 'name' => 'docker:stable-dind', 'entrypoint' => '/bin/sh', 'alias' => 'docker', 'command' => 'sleep 30',
'ports' => [], 'variables' => [], 'pull_policy' => nil },
{ 'name' => 'mysql:latest', 'entrypoint' => nil, 'alias' => nil, 'command' => nil, 'ports' => [],
'variables' => [{ 'key' => 'MYSQL_ROOT_PASSWORD', 'value' => 'root123.' }], 'pull_policy' => nil }
])
expect(json_response['steps']).to eq(expected_steps)
expect(json_response['artifacts']).to eq(expected_artifacts)
expect(json_response['cache']).to match(expected_cache)
@ -849,6 +853,47 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
end
end
context 'when service has pull_policy' do
let(:job) { create(:ci_build, :pending, :queued, pipeline: pipeline, options: options) }
let(:options) do
{
services: [{
name: 'postgres:11.9',
pull_policy: ['if-not-present']
}]
}
end
it 'returns the service with pull policy' do
request_job
expect(response).to have_gitlab_http_status(:created)
expect(json_response).to include(
'id' => job.id,
'services' => [{ 'alias' => nil, 'command' => nil, 'entrypoint' => nil, 'name' => 'postgres:11.9',
'ports' => [], 'pull_policy' => ['if-not-present'], 'variables' => [] }]
)
end
context 'when the FF ci_docker_image_pull_policy is disabled' do
before do
stub_feature_flags(ci_docker_image_pull_policy: false)
end
it 'returns the service without pull policy' do
request_job
expect(response).to have_gitlab_http_status(:created)
expect(json_response).to include(
'id' => job.id,
'services' => [{ 'alias' => nil, 'command' => nil, 'entrypoint' => nil, 'name' => 'postgres:11.9',
'ports' => [], 'variables' => [] }]
)
end
end
end
describe 'a job with excluded artifacts' do
context 'when excluded paths are defined' do
let(:job) do

View File

@ -91,7 +91,6 @@ module UsageDataHelpers
projects_with_repositories_enabled
projects_with_error_tracking_enabled
projects_with_enabled_alert_integrations
projects_with_tracing_enabled
projects_with_expiration_policy_enabled
projects_with_expiration_policy_disabled
projects_with_expiration_policy_enabled_with_keep_n_unset

View File

@ -6,18 +6,24 @@
# - `alert`, alert for which related incidents should be closed
# - `project`, project of the alert
RSpec.shared_examples 'closes related incident if enabled' do
context 'with issue' do
context 'with incident' do
before do
alert.update!(issue: create(:issue, project: project))
alert.update!(issue: create(:incident, project: project))
end
it { expect { subject }.to change { alert.issue.reload.closed? }.from(false).to(true) }
it { expect { subject }.to change(ResourceStateEvent, :count).by(1) }
specify do
expect { Sidekiq::Testing.inline! { subject } }
.to change { alert.issue.reload.closed? }.from(false).to(true)
.and change(ResourceStateEvent, :count).by(1)
end
end
context 'without issue' do
it { expect { subject }.not_to change { alert.reload.issue } }
it { expect { subject }.not_to change(ResourceStateEvent, :count) }
context 'without incident' do
specify do
expect(::IncidentManagement::CloseIncidentWorker).not_to receive(:perform_async)
subject
end
end
context 'with incident setting disabled' do
@ -28,17 +34,23 @@ RSpec.shared_examples 'closes related incident if enabled' do
end
RSpec.shared_examples 'does not close related incident' do
context 'with issue' do
context 'with incident' do
before do
alert.update!(issue: create(:issue, project: project))
alert.update!(issue: create(:incident, project: project))
end
it { expect { subject }.not_to change { alert.issue.reload.state } }
it { expect { subject }.not_to change(ResourceStateEvent, :count) }
specify do
expect { Sidekiq::Testing.inline! { subject } }
.to not_change { alert.issue.reload.state }
.and not_change(ResourceStateEvent, :count)
end
end
context 'without issue' do
it { expect { subject }.not_to change { alert.reload.issue } }
it { expect { subject }.not_to change(ResourceStateEvent, :count) }
context 'without incident' do
specify do
expect(::IncidentManagement::CloseIncidentWorker).not_to receive(:perform_async)
subject
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'dashboard/projects/_blank_state_welcome.html.haml' do
let_it_be(:user) { create(:user) }
before do
allow(view).to receive(:current_user).and_return(user)
end
it 'has a doc_url' do
render
expect(rendered).to have_link(href: Gitlab::Saas.doc_url)
end
end

View File

@ -10,10 +10,6 @@ RSpec.describe 'projects/settings/operations/show' do
create(:project_error_tracking_setting, project: project)
end
let_it_be_with_reload(:tracing_setting) do
create(:project_tracing_setting, project: project)
end
let_it_be(:prometheus_integration) { create(:prometheus_integration, project: project) }
before_all do
@ -25,8 +21,6 @@ RSpec.describe 'projects/settings/operations/show' do
allow(view).to receive(:error_tracking_setting)
.and_return(error_tracking_setting)
allow(view).to receive(:tracing_setting)
.and_return(tracing_setting)
allow(view).to receive(:prometheus_integration)
.and_return(prometheus_integration)
allow(view).to receive(:current_user).and_return(user)
@ -51,14 +45,4 @@ RSpec.describe 'projects/settings/operations/show' do
end
end
end
describe 'Operations > Tracing' do
context 'Settings page ' do
it 'renders the Tracing Settings page' do
render
expect(rendered).to have_content _('Embed an image of your existing Jaeger server in GitLab.')
end
end
end
end

View File

@ -0,0 +1,65 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe IncidentManagement::CloseIncidentWorker do
subject(:worker) { described_class.new }
describe '#perform' do
let_it_be(:user) { User.alert_bot }
let_it_be(:project) { create(:project) }
let_it_be(:issue, reload: true) { create(:incident, project: project) }
let(:issue_id) { issue.id }
it 'calls the close issue service' do
expect_next_instance_of(Issues::CloseService, project: project, current_user: user) do |service|
expect(service).to receive(:execute).with(issue, system_note: false).and_call_original
end
expect { worker.perform(issue_id) }.to change(ResourceStateEvent, :count).by(1)
end
shared_examples 'does not call the close issue service' do
specify do
expect(Issues::CloseService).not_to receive(:new)
expect { worker.perform(issue_id) }.not_to change(ResourceStateEvent, :count)
end
end
context 'when the incident does not exist' do
let(:issue_id) { non_existing_record_id }
it_behaves_like 'does not call the close issue service'
end
context 'when issue type is not incident' do
before do
issue.update!(issue_type: :issue)
end
it_behaves_like 'does not call the close issue service'
end
context 'when incident is not open' do
before do
issue.close
end
it_behaves_like 'does not call the close issue service'
end
context 'when incident fails to close' do
before do
allow_next_instance_of(Issues::CloseService) do |service|
expect(service).to receive(:close_issue).and_return(issue)
end
end
specify do
expect { worker.perform(issue_id) }.not_to change(ResourceStateEvent, :count)
end
end
end
end

View File

@ -1048,10 +1048,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.21.0.tgz#bc71951dc35a61647fb2c0267cca6fb55a04d317"
integrity sha512-cVa5cgvVmY2MsRdV61id+rLTsY/tAGPq7Og9ETblUuZXl06ciw8H/g7cYPMxN39DdEfDklzbUnS98OJlMmD9TQ==
"@gitlab/ui@41.10.0":
version "41.10.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-41.10.0.tgz#20c6475b5b8e47e4eda97d2d76d851191c981251"
integrity sha512-ANxKD7YGSHTPphZE/oGrvyMraLUrC/cll8xGGizipPFo9pza9krobQfBt1tfLMs7DLSbtdmPoIpFjrOLaYM4NA==
"@gitlab/ui@42.7.0":
version "42.7.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-42.7.0.tgz#70e53399d78a2720aa035605c6b194e9352e24c0"
integrity sha512-dsKkjUOvPsu+TzXAe0EOQJrWVrwrYViJ9loCjslweOYJ4wxgukqLpMIQCDCgDTHMdGzjUWENvF98Xle7Vkfl2g==
dependencies:
"@popperjs/core" "^2.11.2"
bootstrap-vue "2.20.1"