lib/release_tools/promotion/production_status.rb (77 lines of code) (raw):

# frozen_string_literal: true module ReleaseTools module Promotion # Perform production checks and report on their statuses # # There is a default group of checks that are always queried. Additional # checks can be included by passing them to the initializer: # # # Additionally include `MyCustomCheck` and `ConditionalCheck` # ProductionStatus.new(:my_custom_check, :conditional_check) class ProductionStatus include ::SemanticLogger::Loggable include Check # Raised when attempting to include an unknown `Check` class class InvalidCheckError < StandardError def initialize(name) super("Unknown check `#{name}`") end end # List of checks that are always included for any production status check ALL_CHECKS = %i[ active_incidents change_requests gitlab_deployment_health orchestrator_status ].freeze attr_reader :checks, :scope def initialize(*extra_checks, scope: :deployment) @scope = scope @checks = [*ALL_CHECKS, *extra_checks].uniq.map do |check_name| instance_of_check(check_name) end end # @see Check#fine? def fine? checks.all?(&:fine?) end # @return <Array(Class)> Array of checks that failed. def failed_checks checks.reject(&:fine?) end # @see Check#to_issue_body def to_issue_body text = StringIO.new overall_status = if fine? "#{ok_icon} Production checks pass." else "#{failure_icon} Production checks fail!" end text.puts(overall_status) checks.each do |check| text.puts("\n---") text.puts(check.to_issue_body) end text.string end # @see Check#to_slack_blocks def to_slack_blocks overall_status = if fine? "#{ok_icon} Production checks pass. :shipit: :fine:" else "#{failure_icon} Production checks fail!" end if fine? [to_slack_block(overall_status)] else [to_slack_block(overall_status)] + checks.reject(&:fine?).map(&:to_slack_blocks).flatten end end private def to_slack_block(status) { type: 'section', text: mrkdwn(status) } end def args_for(check_name) if %i[active_incidents change_requests].include?(check_name) { scope: scope } else {} end end def instance_of_check(check_name) Checks.const_get(check_name.to_s.camelize).new(**args_for(check_name)) rescue NameError => ex raise InvalidCheckError, ex.name end end end end