def fetch(key, ask: true)
      UI.crash!("Key '#{key}' must be a symbol. Example :app_id.") unless key.kind_of?(Symbol)

      option = verify_options_key!(key)

      # Same order as https://docs.fastlane.tools/advanced/#priorities-of-parameters-and-options
      value = if @values.key?(key) && !@values[key].nil?
                @values[key]
              elsif option.env_name && !ENV[option.env_name].nil?
                # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
                ENV[option.env_name].dup if option.verify!(option.auto_convert_value(ENV[option.env_name]))
              elsif self.config_file_options.key?(key)
                self.config_file_options[key]
              else
                option.default_value
              end

      value = option.auto_convert_value(value)
      value = nil if value.nil? && !option.string? # by default boolean flags are false
      return value unless value.nil? && !option.optional && ask

      # fallback to asking
      if Helper.test? || !UI.interactive?
        # Since we don't want to be asked on tests, we'll just call the verify block with no value
        # to raise the exception that is shown when the user passes an invalid value
        set(key, '')
        # If this didn't raise an exception, just raise a default one
        UI.user_error!("No value found for '#{key}'")
      end

      while value.nil?
        UI.important("To not be asked about this value, you can specify it using '#{option.key}'") if ENV["FASTLANE_ONBOARDING_IN_PROCESS"].to_s.length == 0
        value = option.sensitive ? UI.password("#{option.description}: ") : UI.input("#{option.description}: ")
        # Also store this value to use it from now on
        begin
          set(key, value)
        rescue => ex
          puts(ex)
          value = nil
        end
      end

      # It's very, very important to use the self[:my_key] notation
      # as this will make sure to use the `fetch` method
      # that is responsible for auto converting the values into the right
      # data type
      # Found out via https://github.com/fastlane/fastlane/issues/11243
      return self[key]
    end
def fetch(key, ask: true)
      UI.crash!("Key '#{key}' must be a symbol. Example :app_id.") unless key.kind_of?(Symbol)

      option = verify_options_key!(key)

      # Same order as https://docs.fastlane.tools/advanced/#priorities-of-parameters-and-options
      value = if @values.key?(key) && !@values[key].nil?
                @values[key]
              elsif option.env_name && !ENV[option.env_name].nil?
                # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
                ENV[option.env_name].dup if option.verify!(option.auto_convert_value(ENV[option.env_name]))
              elsif self.config_file_options.key?(key)
                self.config_file_options[key]
              else
                option.default_value
              end

      value = option.auto_convert_value(value)
      value = nil if value.nil? && !option.string? # by default boolean flags are false
      return value unless value.nil? && !option.optional && ask

      # fallback to asking
      if Helper.test? || !UI.interactive?
        # Since we don't want to be asked on tests, we'll just call the verify block with no value
        # to raise the exception that is shown when the user passes an invalid value
        set(key, '')
        # If this didn't raise an exception, just raise a default one
        UI.user_error!("No value found for '#{key}'")
      end

      while value.nil?
        UI.important("To not be asked about this value, you can specify it using '#{option.key}'") if ENV["FASTLANE_ONBOARDING_IN_PROCESS"].to_s.length == 0
        value = option.sensitive ? UI.password("#{option.description}: ") : UI.input("#{option.description}: ")
        # Also store this value to use it from now on
        begin
          set(key, value)
        rescue => ex
          puts(ex)
          value = nil
        end
      end

      # It's very, very important to use the self[:my_key] notation
      # as this will make sure to use the `fetch` method
      # that is responsible for auto converting the values into the right
      # data type
      # Found out via https://github.com/fastlane/fastlane/issues/11243
      return self[key]
    end
@!group Actually using the class

 Returns the value for a certain key. fastlane_core tries to fetch the value from different sources
 if 'ask' is true and the value is not present, the user will be prompted to provide a value
 rubocop:disable Metrics/PerceivedComplexity