Skip to content

Extract CI related logic from Git::BaseHooksService into a class

The following discussion from !184163 (merged) should be addressed:

  • @fabiopitino started a discussion: (+1 comment)

    @lauraXD Can we extract a class here that is specific to how CI interprets push options? I think adding another method to Git::BaseHooksService with CI-specific internals is starting to look like we need an abstraction here.

    I've drafted below an idea which we could (in a follow-up MR) reuse in Chain::Skip#push_option_skips_ci? and even better, pass a Ci::PipelineCreation::PushOptions object to Ci::CreatePipelineService instead of a primitive hash, then stored in @command.push_options

    There are many advantages:

    1. Centralized knowledge of how CI uses push options.
    2. Less CI implementation details in Git::BaseHooksService which is already very complex.
    3. Ability to test this in isolation and with fast_spec_helper
    # lib/ci/pipeline_creation/push_options.rb
    class Ci::PipelineCreation::PushOptions
      def initialize(push_options)
        @push_options = push_options&.deep_symbolize_keys[:ci]
      end
    
      def ci_skip?
        !!push_options[:skip] # useful in Chain::Skip
      end
    
      def pipeline_variables
        raw_vars = extract_key_value_pairs_from_push_option(push_options[:variable])
    
        raw_vars.map do |key, value|
          { "key" => key, "variable_type" => "env_var", "secret_value" => value }
        end
      end
      
      def pipeline_inputs
        raw_inputs = extract_key_value_pairs_from_push_option(push_options[:input])
        ::Ci::PipelineCreation::Inputs.parse_params(raw_inputs.to_h)
      end
    
      private
    
      attr_reader :push_options
    
      def extract_key_value_pairs_from_push_option(push_option)
        result = []
        return result unless push_option
    
        push_option.each do |raw_value, _count|
          key, value = raw_value.to_s.split("=", 2)
          next if key.blank? || value.nil?
    
          result << [key, value]
        end
    
        result
      end
    end

    cc @furkanayhan