lib/release_tools/release_managers/schedule.rb (82 lines of code) (raw):

# frozen_string_literal: true module ReleaseTools module ReleaseManagers # Obtaining of release managers for a given major/minor release. class Schedule include ::SemanticLogger::Loggable # Raised when release managers for the specified version can't be found VersionNotFoundError = Class.new(StandardError) # The base interval for retrying operations that failed, in seconds. # # This is set higher than the default as obtaining the release managers # schedule can time out, and it often takes a while before these requests # stop timing out. RETRY_INTERVAL = 5 # Releases SSOT - Contains releases and release manager information. RELEASES_YAML = 'https://gitlab.com/gitlab-com/www-gitlab-com/-/raw/master/data/releases.yml' APPSEC_GROUP_ID = 4_654_006 def initialize @schedule_yaml = nil end # Returns the scheduled major.minor version for today. # # To be deprecated https://gitlab.com/gitlab-com/gl-infra/delivery/-/issues/19851 # # @return [ReleaseTools::Version|NilClass] def active_version Version.new(ReleaseTools::GitlabReleasesGemClient.active_version) end # Returns an Array of users for the current milestone release managers # # @return [Array<Gitlab::ObjectifiedHash>] def active_release_managers authorized_release_managers(active_version) end # Returns an Array of users for the current milestone release managers # # @return [Array<Gitlab::ObjectifiedHash>] def active_appsec_release_managers # Appsec release managers are listed for the previous release appsec_release_managers(Version.new(active_version.previous_minor)) end # Returns the scheduled major.minor version for the given date. # # To be deprecated https://gitlab.com/gitlab-com/gl-infra/delivery/-/issues/19851 # # @param [Date|Time] date # @return [ReleaseTools::Version|NilClass] def version_for_date(date) Version.new(ReleaseTools::GitlabReleasesGemClient.version_for_date(date)) rescue StandardError nil end # Returns the user IDs of the release managers for the current version. # Used to assign to resources such as Issues. # # @param [ReleaseTools::Version] version # @return [Array<Integer>] def ids_for_version(version) authorized_release_managers(version).collect(&:id) end # Returns the usernames of the release managers for the current version. # Used to add/remove access to groups at various GitLab instances. # # @param [ReleaseTools::Version] version # @return [Array<String>] def usernames_for_version(version) authorized_release_managers(version).collect(&:username) end # Returns an Array of users authorized for release manager tasks for current version. # # @param [ReleaseTools::Version] version # @return [Array<Gitlab::ObjectifiedHash>] def authorized_release_managers(version) names = release_manager_names_from_yaml(version) client = ReleaseManagers::Client.new Definitions.new.find_by_name(names).map do |release_manager| client.get_user(release_manager.production) end end # Returns a Hash mapping release manager names with all their attributes. # # @return [Hash<String, Gitlab::ObjectifiedHash>] def group_members members = begin ReleaseManagers::Client.new.members rescue StandardError [] end members.each_with_object({}) do |user, hash| hash[user.name] = user end end # @return [Array<Hash>] def schedule_yaml @schedule_yaml ||= begin YAML.safe_load(download_schedule) || [] rescue StandardError [] end end private def appsec_release_managers(version) names = release_manager_names_from_yaml(version, appsec: true) client = ReleaseTools::GitlabClient.client appsec_members = Retriable.with_context(:api) do client.group_members(APPSEC_GROUP_ID) end appsec_members.select! { |member| names.include?(member.name) } end def release_manager_names_from_yaml(version, appsec: false) not_found = -> { raise VersionNotFoundError } minor = version.to_minor names = schedule_yaml .find(not_found) { |row| row['version'] == minor } return names['appsec'] if appsec names['manager_americas'] | names['manager_apac_emea'] end def download_schedule Retriable.retriable(base_interval: RETRY_INTERVAL) do HTTP.get(RELEASES_YAML).to_s end end end end end