class Gitlab::QA::Report::ReportAsIssue

Constants

MAX_TITLE_LENGTH

Attributes

files[R]
gitlab[R]
project[R]

Public Class Methods

new(token:, input_files:, project: nil, dry_run: false, **kwargs) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 11
def initialize(token:, input_files:, project: nil, dry_run: false, **kwargs)
  @project = project
  @gitlab = (dry_run ? GitlabIssueDryClient : GitlabIssueClient).new(token: token, project: project)
  @files = Array(input_files)
end

Public Instance Methods

invoke!() click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 17
def invoke!
  validate_input!

  run!
end

Private Instance Methods

assert_input_files!(files) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 55
def assert_input_files!(files)
  return if Dir.glob(files).any?

  abort "Please provide valid JUnit report files. No files were found matching `#{files.join(',')}`"
end
assert_project!() click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 49
def assert_project!
  return if project

  abort "Please provide a valid project ID or path with the `-p/--project` option!"
end
create_issue(test) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 79
def create_issue(test)
  gitlab.create_issue(
    title: title_from_test(test),
    description: new_issue_description(test),
    labels: new_issue_labels(test).to_a
  )
end
ee_test?(test) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 123
def ee_test?(test)
  test.file =~ %r{features/ee/(api|browser_ui)}
end
issue_labels(issue) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 87
def issue_labels(issue)
  issue&.labels&.to_set || Set.new
end
new_issue_description(test) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 35
def new_issue_description(test)
  "### Full description\n\n#{search_safe(test.name)}\n\n### File path\n\n#{test.file}"
end
new_issue_labels(test) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 39
def new_issue_labels(test)
  []
end
new_issue_title(test) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 31
def new_issue_title(test)
  "#{partial_file_path(test.file)} | #{search_safe(test.name)}".strip
end
partial_file_path(path) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 131
def partial_file_path(path)
  path.match(/((api|browser_ui).*)/i)[1]
end
pipeline() click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 147
def pipeline
  # Gets the name of the pipeline the test was run in, to be used as the key of a scoped label
  #
  # Tests can be run in several pipelines:
  #   gitlab-qa, nightly, staging, canary, production, preprod, MRs, and the default branch (master/main)
  #
  # Some of those run in their own project, so CI_PROJECT_NAME is the name we need. Those are:
  #   nightly, staging, canary, production, and preprod
  #
  # MR, master/main, and gitlab-qa tests run in gitlab-qa, but we only want to report tests run on
  # master/main because the other pipelines will be monitored by the author of the MR that triggered them.
  # So we assume that we're reporting a master/main pipeline if the project name is 'gitlab-qa'.

  @pipeline ||= Runtime::Env.pipeline_from_project_name
end
pipeline_name_label() click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 108
def pipeline_name_label
  case pipeline
  when 'production'
    'found:gitlab.com'
  when 'canary', 'staging'
    "found:#{pipeline}.gitlab.com"
  when 'preprod'
    'found:pre.gitlab.com'
  when 'staging-orchestrated', 'nightly', QA::Runtime::Env.default_branch
    "found:#{pipeline}"
  else
    raise "No `found:*` label for the `#{pipeline}` pipeline!"
  end
end
quarantine_job?() click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 127
def quarantine_job?
  Runtime::Env.ci_job_name&.include?('quarantine')
end
run!() click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 27
def run!
  raise NotImplementedError
end
search_safe(value) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 143
def search_safe(value)
  value.delete('"')
end
test_results_per_file() { |test_results| ... } click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 61
def test_results_per_file
  Dir.glob(files).each do |path|
    extension = File.extname(path)

    test_results =
      case extension
      when '.json'
        Report::JsonTestResults.new(path)
      when '.xml'
        Report::JUnitTestResults.new(path)
      else
        raise "Unknown extension #{extension}"
      end

    yield test_results
  end
end
title_from_test(test) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 135
def title_from_test(test)
  title = new_issue_title(test)

  return title unless title.length > MAX_TITLE_LENGTH

  "#{title[0...MAX_TITLE_LENGTH - 3]}..."
end
up_to_date_labels(test:, issue: nil, new_labels: Set.new) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 99
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
  labels = issue_labels(issue)
  labels |= new_labels
  ee_test?(test) ? labels << "Enterprise Edition" : labels.delete("Enterprise Edition")
  quarantine_job? ? labels << "quarantine" : labels.delete("quarantine")

  labels
end
update_labels(issue, test, new_labels = Set.new) click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 91
def update_labels(issue, test, new_labels = Set.new)
  labels = up_to_date_labels(test: test, issue: issue, new_labels: new_labels)

  return if issue_labels(issue) == labels

  gitlab.edit_issue(iid: issue.iid, options: { labels: labels.to_a })
end
validate_input!() click to toggle source
# File lib/gitlab/qa/report/report_as_issue.rb, line 43
def validate_input!
  assert_project!
  assert_input_files!(files)
  gitlab.assert_user_permission!
end