# frozen_string_literal: truerequire'set'moduleGitlabmoduleQAmoduleReportclassReportAsIssueMAX_TITLE_LENGTH=255definitialize(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)enddefinvoke!validate_input!run!endprivateattr_reader:gitlab,:files,:project,:issue_typedefrun!raiseNotImplementedErrorenddefnew_issue_title(test)"#{partial_file_path(test.file)} | #{search_safe(test.name)}".stripenddefnew_issue_description(test)"### Full description\n\n#{search_safe(test.name)}\n\n### File path\n\n#{test.file}"enddefnew_issue_labels(test)[]enddefvalidate_input!assert_project!assert_input_files!(files)gitlab.assert_user_permission!enddefassert_project!returnifprojectabort"Please provide a valid project ID or path with the `-p/--project` option!"enddefassert_input_files!(files)returnifDir.glob(files).any?abort"Please provide valid JUnit report files. No files were found matching `#{files.join(',')}`"enddeftest_results_per_fileDir.glob(files).eachdo|path|extension=File.extname(path)test_results=caseextensionwhen'.json'Report::JsonTestResults.new(path)when'.xml'Report::JUnitTestResults.new(path)elseraise"Unknown extension #{extension}"endyieldtest_resultsendenddefcreate_issue(test)issue=gitlab.create_issue(title: title_from_test(test),description: new_issue_description(test),labels: new_issue_labels(test).to_a,issue_type: issue_type)new_link=issue_type=='test_case'?issue.web_url.sub('/issues/','/quality/test_cases/'):issue.web_urlputs"Created new #{issue_type}: #{new_link}"issueenddefissue_labels(issue)issue&.labels&.to_set||Set.newenddefupdate_labels(issue,test,new_labels=Set.new)labels=up_to_date_labels(test: test,issue: issue,new_labels: new_labels)returnifissue_labels(issue)==labelsgitlab.edit_issue(iid: issue.iid,options: {labels: labels.to_a})enddefup_to_date_labels(test:,issue: nil,new_labels: Set.new)labels=issue_labels(issue)labels|=new_labelsee_test?(test)?labels<<'Enterprise Edition':labels.delete('Enterprise Edition')iftest.quarantine?labels<<'quarantine'labels<<"quarantine::#{test.quarantine_type}"elselabels.delete_if{|label|label.include?('quarantine')}endlabelsenddefpipeline_name_labelcasepipelinewhen'production''found:gitlab.com'when'canary','staging'"found:#{pipeline}.gitlab.com"when'staging-canary'"found:canary.staging.gitlab.com"when'preprod''found:pre.gitlab.com'when'nightly',QA::Runtime::Env.default_branch,'staging-ref','release'"found:#{pipeline}"elseraise"No `found:*` label for the `#{pipeline}` pipeline!"endenddefee_test?(test)test.file=~%r{features/ee/(api|browser_ui)}enddefpartial_file_path(path)path.match(/((ee|api|browser_ui).*)/i)[1]enddeftitle_from_test(test)title=new_issue_title(test)returntitleunlesstitle.length>MAX_TITLE_LENGTH"#{title[0...MAX_TITLE_LENGTH-3]}..."enddefsearch_safe(value)value.delete('"')enddefpipeline# 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, 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 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'.@pipeline||=Runtime::Env.pipeline_from_project_nameendendendendend