# frozen_string_literal: true require_relative '../../command' require_relative '../../utils/markdown_lists' require_relative '../../utils/feature_flag_consts' require_relative '../../report' require_relative '../../feature_flag_report' require 'markdown-tables' require 'fileutils' require 'uri' module Dri module Commands class Publish class Report < Dri::Command # rubocop:disable Metrics/ClassLength include Dri::Utils::FeatureFlagConsts def initialize(options) @options = options @date = Date.today @time = Time.now.to_i @today_iso_format = Time.now.strftime('%Y-%m-%dT00:00:00Z') end def execute(input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength verify_config_exists report = Dri::Report.new(config) logger.info "Fetching triaged failures and incidents with award emoji #{emoji}..." spinner.start issues = api_client.fetch_triaged_failures(emoji: emoji, state: 'opened') incidents = api_client.fetch_triaged_incidents(emoji: emoji) spinner.stop if issues.empty? && incidents.empty? logger.warn "Found no issues nor incidents associated with \"#{emoji}\" emoji. Will exit. Bye 👋" exit 1 end logger.info 'Assembling the handover report... ' # sets each failure on the table action_options = [ 'pinged SET', 'reproduced', 'transient', 'quarantined', 'active investigation', 'blocking pipelines', 'awaiting for a fix to merge', 'notified the team', 'due to feature flag' ] spinner.start issues.each do |issue| actions = [] if @options[:actions] actions = prompt.multi_select( "Please mark the actions on #{add_color(issue.title, :yellow)}: ", action_options, per_page: 9 ) end report.add_failure(issue, actions) end unless incidents.empty? incidents.each do |issue| report.add_incident(issue) end end if @options[:format] == 'list' # generates markdown list with failures unless report.failures.empty? failure_report = Utils::MarkdownLists.make_list(report.labels, report.failures) end # generates markdown list with incidents unless report.incidents.empty? incidents_report = Utils::MarkdownLists.make_list(report.labels_incidents, report.incidents) end else # generates markdown table with rows as failures unless report.failures.empty? failure_report = MarkdownTables.make_table( report.labels, report.failures, is_rows: true, align: %w[l l l l l] ) end # generates markdown table with rows as incidents unless report.incidents.empty? incidents_report = MarkdownTables.make_table( report.labels_incidents, report.incidents, is_rows: true, align: %w[l l l l] ) end end spinner.stop if @options[:feature_flags] logger.info 'Fetching today\'s feature flag changes...' feature_flag_report = Dri::FeatureFlagReport.new spinner.start feature_flags = api_client.fetch_feature_flag_logs(@today_iso_format) feature_flags.each do |feature_flag| next unless TITLE_SUBSTRINGS.any? { |substr| feature_flag.title.include?(substr) } feature_flag_report.add_change(feature_flag) end spinner.stop logger.info 'Assembling the feature flags report...' spinner.start feature_flag_note = "\n\n## Feature Flag Changes" feature_flag_changes = '' format_type = @options[:format] == 'list' ? :list : :table feature_flag_report.get_all_flag_changes.each do |env, changes| next if changes.empty? feature_flag_changes += format_feature_flag_changes( env, changes, feature_flag_report.labels, format_type ) end feature_flag_note += if feature_flag_changes.empty? "\n\nNo changes found today" else "\n\n
Click to expand#{feature_flag_changes}
" end spinner.stop end report.set_header(timezone, username) note = "#{report.header}\n\n#{failure_report}\n\n#{incidents_report}" note += feature_flag_note if @options[:feature_flags] # creates an .md file with the report locally in /handover_reports if @options[:dry_run] logger.info 'Downloading the report... ' spinner.start FileUtils.mkdir_p(handover_report_path) report_path = "#{handover_report_path.chomp('/')}/report-#{@date}-#{@time}.md" File.open(report_path, 'a') do |out_file| out_file.puts note end spinner.stop output.puts "Done! ✅\n" logger.success "Report is ready at: #{report_path}" exit 0 end # sends note to the weekly triage report issues = api_client.fetch_current_triage_issue current_issue_iid = issues.first.iid api_client.post_triage_report_note(iid: current_issue_iid, body: note) output.puts "Done! ✅\n" logger.success(<<~MSG) Thanks @#{username}, your report was posted at https://gitlab.com/gitlab-org/quality/pipeline-triage/-/issues/#{current_issue_iid} 🎉 MSG end private def format_feature_flag_changes(env, changes, labels, format_type) unless format_type == :table || format_type == :list raise ArgumentError, 'format_type must be one of type :table or :list' end case format_type when :list formatted_changes = Utils::MarkdownLists.make_list(labels, changes) when :table formatted_changes = MarkdownTables.make_table( labels, changes, is_rows: true, align: %w[l l l] ) end "\n\n### #{env.to_s.capitalize.tr('_', ' ')}\n\n#{formatted_changes}" end end end end end