Commit bfb47d74 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents cde325c6 5fcf206f
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
- knapsack/ - knapsack/
- rspec/ - rspec/
- crystalball/ - crystalball/
when: always
retrieve-tests-metadata: retrieve-tests-metadata:
extends: extends:
......
...@@ -40,7 +40,7 @@ Which tier is this feature available in? ...@@ -40,7 +40,7 @@ Which tier is this feature available in?
- To see who the stable counterparts are for a product team visit [product categories](https://about.gitlab.com/handbook/product/categories/) - To see who the stable counterparts are for a product team visit [product categories](https://about.gitlab.com/handbook/product/categories/)
- If there is no stable counterpart listed for Sales/CS please mention `@timtams` - If there is no stable counterpart listed for Sales/CS please mention `@timtams`
- If there is no stable counterpart listed for Support please @mention `@gitlab-com/support/managers` - If there is no stable counterpart listed for Support please @mention `@gitlab-com/support/managers`
- If there is no stable counterpart listed for Marketing please mention `@williamchia` - If there is no stable counterpart listed for Marketing please mention `@cfoster3`
- [ ] @mention your GPM so that they are aware of planned deprecations. The goal is to have reviews happen at least two releases before the final removal of the feature or introduction of a breaking change. - [ ] @mention your GPM so that they are aware of planned deprecations. The goal is to have reviews happen at least two releases before the final removal of the feature or introduction of a breaking change.
......
...@@ -580,7 +580,7 @@ module Issuable ...@@ -580,7 +580,7 @@ module Issuable
## ##
# Overridden in MergeRequest # Overridden in MergeRequest
# #
def wipless_title_changed(old_title) def draftless_title_changed(old_title)
old_title != title old_title != title
end end
end end
......
...@@ -563,16 +563,22 @@ class MergeRequest < ApplicationRecord ...@@ -563,16 +563,22 @@ class MergeRequest < ApplicationRecord
DRAFT_REGEX = /\A*#{Gitlab::Regex.merge_request_draft}+\s*/i.freeze DRAFT_REGEX = /\A*#{Gitlab::Regex.merge_request_draft}+\s*/i.freeze
def self.work_in_progress?(title) def self.draft?(title)
!!(title =~ DRAFT_REGEX) !!(title =~ DRAFT_REGEX)
end end
def self.wipless_title(title) def self.draftless_title(title)
title.sub(DRAFT_REGEX, "") title.sub(DRAFT_REGEX, "")
end end
def self.wip_title(title) def self.draft_title(title)
work_in_progress?(title) ? title : "Draft: #{title}" draft?(title) ? title : "Draft: #{title}"
end
class << self
alias_method :work_in_progress?, :draft?
alias_method :wipless_title, :draftless_title
alias_method :wip_title, :draft_title
end end
def self.participant_includes def self.participant_includes
...@@ -585,9 +591,10 @@ class MergeRequest < ApplicationRecord ...@@ -585,9 +591,10 @@ class MergeRequest < ApplicationRecord
# Verifies if title has changed not taking into account Draft prefix # Verifies if title has changed not taking into account Draft prefix
# for merge requests. # for merge requests.
def wipless_title_changed(old_title) def draftless_title_changed(old_title)
self.class.wipless_title(old_title) != self.wipless_title self.class.draftless_title(old_title) != self.draftless_title
end end
alias_method :wipless_title_changed, :draftless_title_changed
def hook_attrs def hook_attrs
Gitlab::HookData::MergeRequestBuilder.new(self).build Gitlab::HookData::MergeRequestBuilder.new(self).build
...@@ -1086,18 +1093,20 @@ class MergeRequest < ApplicationRecord ...@@ -1086,18 +1093,20 @@ class MergeRequest < ApplicationRecord
@closed_event ||= target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: :closed).last @closed_event ||= target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: :closed).last
end end
def work_in_progress? def draft?
self.class.work_in_progress?(title) self.class.draft?(title)
end end
alias_method :draft?, :work_in_progress? alias_method :work_in_progress?, :draft?
def wipless_title def draftless_title
self.class.wipless_title(self.title) self.class.draftless_title(self.title)
end end
alias_method :wipless_title, :draftless_title
def wip_title def draft_title
self.class.wip_title(self.title) self.class.draft_title(self.title)
end end
alias_method :wip_title, :draft_title
def mergeable?(skip_ci_check: false, skip_discussions_check: false) def mergeable?(skip_ci_check: false, skip_discussions_check: false)
return false unless mergeable_state?(skip_ci_check: skip_ci_check, return false unless mergeable_state?(skip_ci_check: skip_ci_check,
......
...@@ -71,7 +71,7 @@ module Issuable ...@@ -71,7 +71,7 @@ module Issuable
def create_title_change_note(old_title) def create_title_change_note(old_title)
create_draft_note(old_title) create_draft_note(old_title)
if issuable.wipless_title_changed(old_title) if issuable.draftless_title_changed(old_title)
SystemNoteService.change_title(issuable, issuable.project, current_user, old_title) SystemNoteService.change_title(issuable, issuable.project, current_user, old_title)
end end
end end
......
...@@ -22,4 +22,4 @@ ...@@ -22,4 +22,4 @@
.col-md-4.col-lg-5.text-right-md.gl-mt-2 .col-md-4.col-lg-5.text-right-md.gl-mt-2
%span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm btn-default gl-mr-3' %span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm btn-default gl-mr-3'
%span>= link_to _('Edit'), edit_hook_path(hook), class: 'btn gl-button btn-default btn-sm gl-mr-3' %span>= link_to _('Edit'), edit_hook_path(hook), class: 'btn gl-button btn-default btn-sm gl-mr-3'
= link_to _('Delete'), destroy_hook_path(hook), data: { confirm: _('Are you sure?') }, method: :delete, class: 'btn gl-button btn-secondary btn-danger-secondary btn-sm' = link_to _('Delete'), destroy_hook_path(hook), aria: { label: s_('Webhooks|Delete webhook') }, data: { confirm_btn_variant: "danger", confirm: s_('Webhooks|Are you sure you want to delete this webhook?') }, method: :delete, class: 'btn gl-button btn-secondary btn-danger-secondary btn-sm'
...@@ -40375,6 +40375,9 @@ msgstr "" ...@@ -40375,6 +40375,9 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened." msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr "" msgstr ""
msgid "Webhooks|Are you sure you want to delete this webhook?"
msgstr ""
msgid "Webhooks|Comments" msgid "Webhooks|Comments"
msgstr "" msgstr ""
...@@ -40384,6 +40387,9 @@ msgstr "" ...@@ -40384,6 +40387,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events" msgid "Webhooks|Confidential issues events"
msgstr "" msgstr ""
msgid "Webhooks|Delete webhook"
msgstr ""
msgid "Webhooks|Deployment events" msgid "Webhooks|Deployment events"
msgstr "" msgstr ""
......
...@@ -209,6 +209,8 @@ function debug_rspec_variables() { ...@@ -209,6 +209,8 @@ function debug_rspec_variables() {
echoinfo "NEW_FLAKY_RSPEC_REPORT_PATH: ${NEW_FLAKY_RSPEC_REPORT_PATH}" echoinfo "NEW_FLAKY_RSPEC_REPORT_PATH: ${NEW_FLAKY_RSPEC_REPORT_PATH}"
echoinfo "SKIPPED_FLAKY_TESTS_REPORT_PATH: ${SKIPPED_FLAKY_TESTS_REPORT_PATH}" echoinfo "SKIPPED_FLAKY_TESTS_REPORT_PATH: ${SKIPPED_FLAKY_TESTS_REPORT_PATH}"
echoinfo "RETRIED_TESTS_REPORT_PATH: ${RETRIED_TESTS_REPORT_PATH}" echoinfo "RETRIED_TESTS_REPORT_PATH: ${RETRIED_TESTS_REPORT_PATH}"
echoinfo "CRYSTALBALL: ${CRYSTALBALL}"
} }
function rspec_paralellized_job() { function rspec_paralellized_job() {
...@@ -245,11 +247,7 @@ function rspec_paralellized_job() { ...@@ -245,11 +247,7 @@ function rspec_paralellized_job() {
cp "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" "${KNAPSACK_REPORT_PATH}" cp "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" "${KNAPSACK_REPORT_PATH}"
if [[ -z "${KNAPSACK_TEST_FILE_PATTERN}" ]]; then export KNAPSACK_TEST_FILE_PATTERN=$(ruby -r./tooling/quality/test_level.rb -e "puts Quality::TestLevel.new(${spec_folder_prefixes}).pattern(:${test_level})")
pattern=$(ruby -r./tooling/quality/test_level.rb -e "puts Quality::TestLevel.new(${spec_folder_prefixes}).pattern(:${test_level})")
export KNAPSACK_TEST_FILE_PATTERN="${pattern}"
fi
export FLAKY_RSPEC_REPORT_PATH="${rspec_flaky_folder_path}all_${report_name}_report.json" export FLAKY_RSPEC_REPORT_PATH="${rspec_flaky_folder_path}all_${report_name}_report.json"
export NEW_FLAKY_RSPEC_REPORT_PATH="${rspec_flaky_folder_path}new_${report_name}_report.json" export NEW_FLAKY_RSPEC_REPORT_PATH="${rspec_flaky_folder_path}new_${report_name}_report.json"
export SKIPPED_FLAKY_TESTS_REPORT_PATH="${rspec_flaky_folder_path}skipped_flaky_tests_${report_name}_report.txt" export SKIPPED_FLAKY_TESTS_REPORT_PATH="${rspec_flaky_folder_path}skipped_flaky_tests_${report_name}_report.txt"
...@@ -285,6 +283,18 @@ function rspec_paralellized_job() { ...@@ -285,6 +283,18 @@ function rspec_paralellized_job() {
# Experiment to retry failed examples in a new RSpec process: https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1148 # Experiment to retry failed examples in a new RSpec process: https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1148
if [[ $rspec_run_status -ne 0 ]]; then if [[ $rspec_run_status -ne 0 ]]; then
if [[ "${RETRY_FAILED_TESTS_IN_NEW_PROCESS}" == "true" ]]; then if [[ "${RETRY_FAILED_TESTS_IN_NEW_PROCESS}" == "true" ]]; then
$rspec_run_status=$(retry_failed_rspec_examples)
fi
else
echosuccess "No examples to retry, congrats!"
fi
exit $rspec_run_status
}
function retry_failed_rspec_examples() {
local rspec_run_status=0
# Keep track of the tests that are retried, later consolidated in a single file by the `rspec:flaky-tests-report` job # Keep track of the tests that are retried, later consolidated in a single file by the `rspec:flaky-tests-report` job
local failed_examples=$(grep " failed" ${RSPEC_LAST_RUN_RESULTS_FILE}) local failed_examples=$(grep " failed" ${RSPEC_LAST_RUN_RESULTS_FILE})
echo "${CI_JOB_URL}" > "${RETRIED_TESTS_REPORT_PATH}" echo "${CI_JOB_URL}" > "${RETRIED_TESTS_REPORT_PATH}"
...@@ -294,18 +304,17 @@ function rspec_paralellized_job() { ...@@ -294,18 +304,17 @@ function rspec_paralellized_job() {
install_junit_merge_gem install_junit_merge_gem
# Disable Crystalball on retry to not overwrite the existing report
export CRYSTALBALL="false"
# Retry only the tests that failed on first try # Retry only the tests that failed on first try
rspec_simple_job "--only-failures" "${JUNIT_RETRY_FILE}" rspec_simple_job "--only-failures --pattern \"${KNAPSACK_TEST_FILE_PATTERN}\"" "${JUNIT_RETRY_FILE}"
rspec_run_status=$? rspec_run_status=$?
# Merge the JUnit report from retry into the first-try report # 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}"
fi
else
echosuccess "No examples to retry, congrats!"
fi
exit $rspec_run_status return $rspec_run_status
} }
function rspec_rerun_previous_failed_tests() { function rspec_rerun_previous_failed_tests() {
......
...@@ -6,7 +6,7 @@ module CrystalballEnv ...@@ -6,7 +6,7 @@ module CrystalballEnv
extend self extend self
def start! def start!
return unless ENV['CRYSTALBALL'] return unless ENV['CRYSTALBALL'] == 'true'
require 'crystalball' require 'crystalball'
require_relative '../tooling/lib/tooling/crystalball/coverage_lines_execution_detector' require_relative '../tooling/lib/tooling/crystalball/coverage_lines_execution_detector'
......
...@@ -39,11 +39,23 @@ RSpec.describe Tooling::TestMapGenerator do ...@@ -39,11 +39,23 @@ RSpec.describe Tooling::TestMapGenerator do
YAML YAML
end end
let(:yaml3) do
<<~YAML
---
:type: Crystalball::ExecutionMap
:commit: 74056e8d9cf3773f43faa1cf5416f8779c8284c9
:timestamp: 1602671965
:version:
---
YAML
end
let(:pathname) { instance_double(Pathname) } let(:pathname) { instance_double(Pathname) }
before do before do
stub_file_read('yaml1.yml', content: yaml1) stub_file_read('yaml1.yml', content: yaml1)
stub_file_read('yaml2.yml', content: yaml2) stub_file_read('yaml2.yml', content: yaml2)
stub_file_read('yaml3.yml', content: yaml3)
end end
context 'with single yaml' do context 'with single yaml' do
...@@ -74,6 +86,10 @@ RSpec.describe Tooling::TestMapGenerator do ...@@ -74,6 +86,10 @@ RSpec.describe Tooling::TestMapGenerator do
expect(subject.mapping[file]).to match_array(tests) expect(subject.mapping[file]).to match_array(tests)
end end
end end
it 'displays a warning when report has no examples' do
expect { subject.parse('yaml3.yml') }.to output(%|No examples in yaml3.yml! Metadata: {:type=>"Crystalball::ExecutionMap", :commit=>"74056e8d9cf3773f43faa1cf5416f8779c8284c9", :timestamp=>1602671965, :version=>nil}\n|).to_stdout
end
end end
context 'with multiple yamls' do context 'with multiple yamls' do
......
...@@ -12,7 +12,12 @@ module Tooling ...@@ -12,7 +12,12 @@ module Tooling
def parse(yaml_files) def parse(yaml_files)
Array(yaml_files).each do |yaml_file| Array(yaml_files).each do |yaml_file|
data = File.read(yaml_file) data = File.read(yaml_file)
_metadata, example_groups = data.split("---\n").reject(&:empty?).map { |yml| YAML.safe_load(yml, [Symbol]) } metadata, example_groups = data.split("---\n").reject(&:empty?).map { |yml| YAML.safe_load(yml, [Symbol]) }
if example_groups.nil?
puts "No examples in #{yaml_file}! Metadata: #{metadata}"
next
end
example_groups.each do |example_id, files| example_groups.each do |example_id, files|
files.each do |file| files.each do |file|
......
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