Commit b060b8b7 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 49a923c6
......@@ -11,7 +11,7 @@
SEED_CYCLE_ANALYTICS: "true"
SEED_PRODUCTIVITY_ANALYTICS: "true"
CYCLE_ANALYTICS_ISSUE_COUNT: 1
SIZE: 0 # number of external projects to fork, requires network connection
SIZE: 0 # number of external projects to fork, requires network connection
# SEED_NESTED_GROUPS: "false" # requires network connection
run-dev-fixtures:
......
......@@ -157,9 +157,9 @@ dast:
extends:
- .default-retry
- .reports:rules:dast
needs:
- job: review-deploy
artifacts: true
# This is needed so that manual jobs with needs don't block the pipeline.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
dependencies: ["review-deploy"]
stage: qa # GitLab-specific
image:
name: "registry.gitlab.com/gitlab-org/security-products/dast:$DAST_VERSION"
......
......@@ -15,7 +15,7 @@
build-qa-image:
extends:
- .review-docker
- .review:rules:mr-and-schedule
- .review:rules:mr-and-schedule-auto
stage: prepare
script:
- '[[ ! -d "ee/" ]] || export GITLAB_EDITION="ee"'
......@@ -45,7 +45,7 @@ review-cleanup:
review-build-cng:
extends:
- .default-retry
- .review:rules:mr-and-schedule
- .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
image: ruby:2.6-alpine
stage: review-prepare
before_script:
......@@ -57,6 +57,9 @@ review-build-cng:
artifacts: false
script:
- BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng
# When the job is manual, review-deploy is also manual and we don't want people
# to have to manually start the jobs in sequence, so we do it for them.
- '[ -z $CI_JOB_MANUAL ] || play_job "review-deploy"'
.review-workflow-base:
extends:
......@@ -76,11 +79,9 @@ review-build-cng:
review-deploy:
extends:
- .review-workflow-base
- .review:rules:mr-and-schedule
- .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
stage: review
needs:
- job: review-build-cng
artifacts: false
dependencies: []
resource_group: "review/${CI_COMMIT_REF_NAME}"
allow_failure: true
before_script:
......@@ -100,6 +101,10 @@ review-deploy:
- download_chart
- date
- deploy || (display_deployment_debug && exit 1)
# When the job is manual, review-qa-smoke is also manual and we don't want people
# to have to manually start the jobs in sequence, so we do it for them.
- '[ -z $CI_JOB_MANUAL ] || play_job "review-qa-smoke"'
- '[ -z $CI_JOB_MANUAL ] || play_job "review-performance"'
artifacts:
paths: [environment_url.txt]
expire_in: 2 days
......@@ -140,9 +145,9 @@ review-stop:
.review-qa-base:
extends: .review-docker
stage: qa
needs:
- job: review-deploy
artifacts: true
# This is needed so that manual jobs with needs don't block the pipeline.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
dependencies: ["review-deploy"]
allow_failure: true
variables:
QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
......@@ -172,7 +177,7 @@ review-stop:
review-qa-smoke:
extends:
- .review-qa-base
- .review:rules:mr-only-auto
- .review:rules:mr-only-auto-if-frontend-manual-otherwise
script:
- gitlab-qa Test::Instance::Smoke "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
......@@ -189,11 +194,11 @@ review-qa-all:
review-performance:
extends:
- .review-docker
- .review:rules:mr-and-schedule
- .review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise
stage: qa
needs:
- job: review-deploy
artifacts: true
# This is needed so that manual jobs with needs don't block the pipeline.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/199979.
dependencies: ["review-deploy"]
allow_failure: true
before_script:
- export CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
......
......@@ -57,6 +57,17 @@
- "doc/**/*"
- ".markdownlint.json"
.frontend-dependency-patterns: &frontend-dependency-patterns
- "{package.json,yarn.lock}"
.frontend-patterns: &frontend-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
- "{,ee/}{app/assets,app/helpers,app/presenters,app/views,locale,public,symbol}/**/*"
.backstage-patterns: &backstage-patterns
- "Dangerfile"
- "danger/**/*"
......@@ -66,39 +77,38 @@
- "doc/README.md" # Some RSpec test rely on this file
.code-patterns: &code-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
- ".gitlab/ci/**/*"
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,scss-lint}.yml"
- ".csscomb.json"
- "Dockerfile.assets"
- "*_VERSION"
- "Gemfile{,.lock}"
- "Rakefile"
- "{babel.config,jest.config}.js"
- "config.ru"
- "{package.json,yarn.lock}"
- "{,ee/}{app,bin,config,db,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated
.frontend-dependency-patterns: &frontend-dependency-patterns
- "{package.json,yarn.lock}"
.qa-patterns: &qa-patterns
- ".dockerignore"
- "qa/**/*"
.code-backstage-patterns: &code-backstage-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
- ".gitlab/ci/**/*"
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,scss-lint}.yml"
- ".csscomb.json"
- "Dockerfile.assets"
- "*_VERSION"
- "Gemfile{,.lock}"
- "Rakefile"
- "{babel.config,jest.config}.js"
- "config.ru"
- "{package.json,yarn.lock}"
- "{,ee/}{app,bin,config,db,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated
# Backstage changes
......@@ -110,17 +120,18 @@
- "doc/README.md" # Some RSpec test rely on this file
.code-qa-patterns: &code-qa-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
- ".gitlab/ci/**/*"
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,scss-lint}.yml"
- ".csscomb.json"
- "Dockerfile.assets"
- "*_VERSION"
- "Gemfile{,.lock}"
- "Rakefile"
- "{babel.config,jest.config}.js"
- "config.ru"
- "{package.json,yarn.lock}"
- "{,ee/}{app,bin,config,db,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated
# QA changes
......@@ -128,17 +139,18 @@
- "qa/**/*"
.code-backstage-qa-patterns: &code-backstage-qa-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
- ".gitlab/ci/**/*"
- ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".{codeclimate,eslintrc,gitlab-ci,haml-lint,haml-lint_todo,rubocop,rubocop_todo,scss-lint}.yml"
- ".csscomb.json"
- "Dockerfile.assets"
- "*_VERSION"
- "Gemfile{,.lock}"
- "Rakefile"
- "{babel.config,jest.config}.js"
- "config.ru"
- "{package.json,yarn.lock}"
- "{,ee/}{app,bin,config,db,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated
# Backstage changes
......@@ -416,8 +428,12 @@
rules:
- if: '$DAST_DISABLED || $GITLAB_FEATURES !~ /\bdast\b/'
when: never
- <<: *if-dot-com-gitlab-org-merge-request
changes: *frontend-patterns
when: on_success
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-qa-patterns
when: manual
.reports:schedule-dast:
rules:
......@@ -428,7 +444,7 @@
################
# Review rules #
################
.review:rules:mr-and-schedule:
.review:rules:mr-and-schedule-auto:
rules:
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-qa-patterns
......@@ -436,12 +452,33 @@
- <<: *if-dot-com-gitlab-org-schedule
when: on_success
.review:rules:mr-and-schedule-auto-if-frontend-manual-otherwise:
rules:
- <<: *if-dot-com-gitlab-org-merge-request
changes: *frontend-patterns
when: on_success
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-qa-patterns
when: manual
allow_failure: true
- <<: *if-dot-com-gitlab-org-schedule
when: on_success
.review:rules:mr-only-auto:
rules:
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-qa-patterns
when: on_success
.review:rules:mr-only-auto-if-frontend-manual-otherwise:
rules:
- <<: *if-dot-com-gitlab-org-merge-request
changes: *frontend-patterns
when: on_success
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-qa-patterns
when: manual
.review:rules:mr-only-manual:
rules:
- <<: *if-dot-com-gitlab-org-merge-request
......
......@@ -41,7 +41,7 @@ class Admin::ServicesController < Admin::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def service
@service ||= Service.where(id: params[:id], template: true).first
@service ||= Service.find_by(id: params[:id], template: true)
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -4,7 +4,13 @@ module ImportUrlParams
def import_url_params
return {} unless params.dig(:project, :import_url).present?
{ import_url: import_params_to_full_url(params[:project]) }
{
import_url: import_params_to_full_url(params[:project]),
# We need to set import_type because attempting to retry an import by URL
# could leave a stale value around. This would erroneously cause an importer
# (e.g. import/export) to run.
import_type: 'git'
}
end
def import_params_to_full_url(params)
......
......@@ -55,6 +55,19 @@ module Emails
reply_to: @message.reply_to,
subject: @message.subject)
end
def prometheus_alert_fired_email(project_id, user_id, alert_payload)
@project = ::Project.find(project_id)
user = ::User.find(user_id)
@alert = ::Gitlab::Alerting::Alert
.new(project: @project, payload: alert_payload)
.present
return unless @alert.valid?
subject_text = "Alert: #{@alert.full_title}"
mail(to: user.notification_email_for(@project.group), subject: subject(subject_text))
end
end
end
......
......@@ -523,6 +523,14 @@ class NotificationService
end
end
def prometheus_alerts_fired(project, alerts)
return if project.emails_disabled?
owners_and_maintainers_without_invites(project).to_a.product(alerts).each do |recipient, alert|
mailer.prometheus_alert_fired_email(project.id, recipient.user.id, alert).deliver_later
end
end
protected
def new_resource_email(target, method)
......@@ -618,6 +626,16 @@ class NotificationService
private
def owners_and_maintainers_without_invites(project)
recipients = project.members.active_without_invites_and_requests.owners_and_maintainers
if recipients.empty? && project.group
recipients = project.group.members.active_without_invites_and_requests.owners_and_maintainers
end
recipients
end
def project_maintainers_recipients(target, action:)
NotificationRecipients::BuildService.build_project_maintainers_recipients(target, action: action)
end
......
%p
= _('An alert has been triggered in %{project_path}.') % { project_path: @alert.project_full_path }
- if description = @alert.description
%p
= _('Description:')
= description
- if env_name = @alert.environment_name
%p
= _('Environment:')
= env_name
- if metric_query = @alert.metric_query
%p
= _('Metric:')
%pre
= metric_query
- if @alert.show_incident_issues_link?
%p
= link_to(_('View incident issues.'), @alert.incident_issues_link)
- if @alert.show_performance_dashboard_link?
%p
= link_to(_('View performance dashboard.'), @alert.performance_dashboard_link)
<%= _('An alert has been triggered in %{project_path}.') % { project_path: @alert.project_full_path } %>.
<% if description = @alert.description %>
<%= _('Description:') %> <%= description %>
<% end %>
<% if env_name = @alert.environment_name %>
<%= _('Environment:') %> <%= env_name %>
<% end %>
<% if metric_query = @alert.metric_query %>
<%= _('Metric:') %> <%= metric_query %>
<% end %>
<% if @alert.show_incident_issues_link? %>
<%= _('View incident issues.') %> <%= @alert.incident_issues_link %>
<% end %>
<% if @alert.show_performance_dashboard_link? %>
<%= _('View the performance dashboard at') %> <%= @alert.performance_dashboard_link %>
<% end %>
---
title: Ensure import by URL works after a failed import
merge_request: 27546
author:
type: fixed
# frozen_string_literal: true
class AddsSha256ToPackageFiles < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :packages_package_files, :file_sha256, :binary
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_03_16_111759) do
ActiveRecord::Schema.define(version: 2020_03_18_152134) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
......@@ -3057,6 +3057,7 @@ ActiveRecord::Schema.define(version: 2020_03_16_111759) do
t.binary "file_sha1"
t.string "file_name", null: false
t.text "file", null: false
t.binary "file_sha256"
t.index ["package_id", "file_name"], name: "index_packages_package_files_on_package_id_and_file_name"
end
......
......@@ -133,7 +133,9 @@ and included in `rules` definitions via [YAML anchors](../ci/yaml/README.md#anch
|------------------------------|--------------------------------------------------------------------------|
| `yaml-patterns` | Only create job for YAML-related changes. |
| `docs-patterns` | Only create job for docs-related changes. |
| `backstage-patterns` | Only create job for backstage-related changes. |
| `frontend-dependency-patterns` | Only create job when frontend dependencies are updated (i.e. `package.json`, and `yarn.lock`). changes. |
| `frontend-patterns` | Only create job for frontend-related changes. |
| `backstage-patterns` | Only create job for backstage-related changes (i.e. Danger, fixtures, RuboCop, specs). |
| `code-patterns` | Only create job for code-related changes. |
| `qa-patterns` | Only create job for QA-related changes. |
| `code-backstage-patterns` | Combination of `code-patterns` and `backstage-patterns`. |
......
......@@ -51,7 +51,7 @@ The Dashboard is the default view of the Admin Area, and is made up of the follo
| Section | Description |
|:-----------|:---------------------------------------------------------------------------------------------------------------------------------------------------------|
| Projects | The total number of projects, up to 10 of the latest projects, and the option of creating a new project. |
| Users | The total number of users, up to 10 of the latest users, and the option of creating a new user. |
| Users | The total number of users, up to 10 of the latest users, the option of creating a new user, and a link to [**Users statistics**](#users-statistics). |
| Groups | The total number of groups, up to 10 of the latest groups, and the option of creating a new group. |
| Statistics | Totals of all elements of the GitLab instance. |
| Features | All features available on the GitLab instance. Enabled features are marked with a green circle icon, and disabled features are marked with a power icon. |
......@@ -134,6 +134,19 @@ To search for users, enter your criteria in the search field. The user search is
insensitive, and applies partial matching to name and username. To search for an email address,
you must provide the complete email address.
#### Users statistics
The **Users statistics** page provides an overview of user accounts by role. Use this information
when validating seat usage of your subscription.
The page displays subtotals of all users matching criteria such as _Users with highest role
Maintainer_ and _Blocked users_.
The **Total users** is calculated as: **Active users** + **Blocked users**.
GitLab billing is based on the number of active users. For details of active users, see
[Choosing the number of users](../../subscriptions/index.md#choosing-the-number-of-users).
### Administering Groups
You can administer all groups in the GitLab instance from the Admin Area's Groups page.
......
......@@ -245,7 +245,7 @@ project):
```yaml
include:
template: Serverless.gitlab-ci.yml
- template: Serverless.gitlab-ci.yml
functions:build:
extends: .serverless:build:functions
......@@ -462,7 +462,7 @@ Add the following `.gitlab-ci.yml` to the root of your repository
```yaml
include:
template: Serverless.gitlab-ci.yml
- template: Serverless.gitlab-ci.yml
build:
extends: .serverless:build:image
......
......@@ -57,3 +57,54 @@ function echoinfo() {
printf "\033[0;33m%s\n\033[0m" "${1}" >&2;
fi
}
function get_job_id() {
local job_name="${1}"
local query_string="${2:+&${2}}"
local api_token="${API_TOKEN-${GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN}}"
if [ -z "${api_token}" ]; then
echoerr "Please provide an API token with \$API_TOKEN or \$GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN."
return
fi
local max_page=3
local page=1
while true; do
local url="https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs?per_page=100&page=${page}${query_string}"
echoinfo "GET ${url}"
local job_id
job_id=$(curl --silent --show-error --header "PRIVATE-TOKEN: ${api_token}" "${url}" | jq "map(select(.name == \"${job_name}\")) | map(.id) | last")
[[ "${job_id}" == "null" && "${page}" -lt "$max_page" ]] || break
let "page++"
done
if [[ "${job_id}" == "" ]]; then
echoerr "The '${job_name}' job ID couldn't be retrieved!"
else
echoinfo "The '${job_name}' job ID is ${job_id}"
echo "${job_id}"
fi
}
function play_job() {
local job_name="${1}"
local job_id
job_id=$(get_job_id "${job_name}" "scope=manual");
if [ -z "${job_id}" ]; then return; fi
local api_token="${API_TOKEN-${GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN}}"
if [ -z "${api_token}" ]; then
echoerr "Please provide an API token with \$API_TOKEN or \$GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN."
return
fi
local url="https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/jobs/${job_id}/play"
echoinfo "POST ${url}"
local job_url
job_url=$(curl --silent --show-error --request POST --header "PRIVATE-TOKEN: ${api_token}" "${url}" | jq ".web_url")
echoinfo "Manual job '${job_name}' started at: ${job_url}"
}
......@@ -31,7 +31,8 @@ describe ImportUrlParams do
describe '#import_url_params' do
it 'returns hash with import_url' do
expect(import_url_params).to eq(
import_url: "https://user:password@url.com"
import_url: "https://user:password@url.com",
import_type: 'git'
)
end
end
......@@ -48,7 +49,8 @@ describe ImportUrlParams do
describe '#import_url_params' do
it 'does not change the url' do
expect(import_url_params).to eq(
import_url: "https://user:password@url.com"
import_url: "https://user:password@url.com",
import_type: 'git'
)
end
end
......
# frozen_string_literal: true
require 'spec_helper'
require 'email_spec'
describe Emails::Projects do
include EmailSpec::Matchers
include_context 'gitlab email notification'
shared_examples 'no email' do
it 'does not send mail' do
expect(subject.message).to be_a_kind_of(ActionMailer::Base::NullMail)
end
end
shared_examples 'shows the incident issues url' do
context 'create issue setting enabled' do
before do
create(:project_incident_management_setting, project: project, create_issue: true)
end
let(:incident_issues_url) do
project_issues_url(project, label_name: 'incident')
end
it { is_expected.to have_body_text(incident_issues_url) }
end
end
let_it_be(:user) { create(:user) }
describe '#prometheus_alert_fired_email' do
subject do
Notify.prometheus_alert_fired_email(project.id, user.id, alert_params)
end
let(:alert_params) do
{ 'startsAt' => Time.now.rfc3339 }
end
context 'with a gitlab alert' do
before do
alert_params['labels'] = { 'gitlab_alert_id' => alert.prometheus_metric_id.to_s }
end
let(:title) do
"#{alert.title} #{alert.computed_operator} #{alert.threshold}"
end
let(:metrics_url) do
metrics_project_environment_url(project, environment)
end
let(:environment) { alert.environment }
let!(:alert) { create(:prometheus_alert, project: project) }
it_behaves_like 'an email sent from GitLab'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like 'a user cannot unsubscribe through footer link'
it 'has expected subject' do
is_expected.to have_subject("#{project.name} | Alert: #{environment.name}: #{title} for 5 minutes")
end
it 'has expected content' do
is_expected.to have_body_text('An alert has been triggered')
is_expected.to have_body_text(project.full_path)
is_expected.to have_body_text('Environment:')
is_expected.to have_body_text(environment.name)
is_expected.to have_body_text('Metric:')
is_expected.to have_body_text(alert.full_query)
is_expected.to have_body_text(metrics_url)
end
it_behaves_like 'shows the incident issues url'
end
context 'with no payload' do
let(:alert_params) { {} }
it_behaves_like 'no email'
end
context 'with an unknown alert' do
before do
alert_params['labels'] = { 'gitlab_alert_id' => 'unknown' }
end
it_behaves_like 'no email'
end
context 'with an external alert' do
let(:title) { 'alert title' }
let(:metrics_url) do
metrics_project_environments_url(project)
end
before do
alert_params['annotations'] = { 'title' => title }
alert_params['generatorURL'] = 'http://localhost:9090/graph?g0.expr=vector%281%29&g0.tab=1'
end
it_behaves_like 'an email sent from GitLab'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like 'a user cannot unsubscribe through footer link'
it 'has expected subject' do
is_expected.to have_subject("#{project.name} | Alert: #{title}")
end
it 'has expected content' do
is_expected.to have_body_text('An alert has been triggered')
is_expected.to have_body_text(project.full_path)
is_expected.not_to have_body_text('Description:')
is_expected.not_to have_body_text('Environment:')
end
context 'with annotated description' do
let(:description) { 'description' }
before do
alert_params['annotations']['description'] = description
end
it 'shows the description' do
is_expected.to have_body_text('Description:')
is_expected.to have_body_text(description)
end
end
it_behaves_like 'shows the incident issues url'
end
end
end
......@@ -2783,6 +2783,41 @@ describe NotificationService, :mailer do
end
end
describe '#prometheus_alerts_fired' do
let!(:project) { create(:project) }
let!(:prometheus_alert) { create(:prometheus_alert, project: project) }
let!(:master) { create(:user) }
let!(:developer) { create(:user) }
before do
project.add_master(master)
end
it 'sends the email to owners and masters' do
expect(Notify).to receive(:prometheus_alert_fired_email).with(project.id, master.id, prometheus_alert).and_call_original
expect(Notify).to receive(:prometheus_alert_fired_email).with(project.id, project.owner.id, prometheus_alert).and_call_original
expect(Notify).not_to receive(:prometheus_alert_fired_email).with(project.id, developer.id, prometheus_alert)
subject.prometheus_alerts_fired(prometheus_alert.project, [prometheus_alert])
end
it_behaves_like 'project emails are disabled' do
before do
allow_next_instance_of(::Gitlab::Alerting::Alert) do |instance|
allow(instance).to receive(:valid?).and_return(true)
end
end
let(:alert_params) { { 'labels' => { 'gitlab_alert_id' => 'unknown' } } }
let(:notification_target) { prometheus_alert.project }
let(:notification_trigger) { subject.prometheus_alerts_fired(prometheus_alert.project, [alert_params]) }
around do |example|
perform_enqueued_jobs { example.run }
end
end
end
def build_team(project)
@u_watcher = create_global_setting_for(create(:user), :watch)
@u_participating = create_global_setting_for(create(:user), :participating)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment