lib/gitlab/qa/component/project_importer.rb



# frozen_string_literal: true

module Gitlab
  module QA
    module Component
      class ProjectImporter < Base
        IMPORT_TIMEOUT = 300 # 5 minutes

        def initialize(project_url, project_name, project_path: project_name)
          @project_name = project_name
          @project_url = project_url
          @project_path = project_path
        end

        def import_project(gitlab)
          import_command = build_import_command(create_import_script, @project_url, @project_name, @project_path)
          puts gitlab.docker.exec(gitlab.name, import_command)
        end

        private

        def create_import_script
          <<~'RUBY'
            require 'timeout'

            project_url = ENV.fetch('PROJECT_URL')
            project_name = ENV.fetch('PROJECT_NAME')
            project_path = ENV.fetch('PROJECT_PATH')

            root_user = User.find_by_username('root')

            project = Projects::CreateService.new(root_user,
              { name: project_name, path: project_path, import_url: project_url }).execute

            if project.persisted?
              # Wait for import to complete
              begin
                Timeout.timeout(300) do # 5 minutes timeout
                  until ['finished', 'failed'].include?(project.import_status)
                    sleep 5
                    project.reload
                  end
                end
              rescue Timeout::Error
                puts "Import process timed out after 5 minutes"
              end
            else
              puts "Failed to create project: #{project.errors.full_messages.join(', ')}"
            end

            # Always print import state for debugging
            puts "Import state: #{project.import_state.attributes}" if project.respond_to?(:import_state)
          RUBY
        end

        def build_import_command(script, project_url, project_name, project_path)
          escaped_script = script.gsub("'", "\\\\'").gsub("\n", "\\n")
          "PROJECT_URL='#{project_url}' PROJECT_NAME='#{project_name}' PROJECT_PATH='#{project_path}' gitlab-rails runner $'#{escaped_script}'"
        end
      end
    end
  end
end