Skip to content
  • I made a quick & dirty modification to fix assignees for MRs:

    require 'json'
    require 'net/http'
    require 'uri'
    
    source_instance = {
        uri: URI('https://gitlab.com'),
        access_token: '<insert token here>'
      }
      
      target_instance = {
        uri: URI('http://localhost:3000'),
        access_token: '<insert token here>'
      }
      
      namespaces = [
        '<some namespace>',
        '<some namespace>/<subgroup>',
      ].map{ |namespace| namespace.sub('/', '%2F') }  
    
    def api_request(instance, method, endpoint)
      unless instance[:http]
        instance[:http] = Net::HTTP.new(instance[:uri].host, instance[:uri].port)
        instance[:http].use_ssl = true if instance[:uri].scheme == 'https'
      end
    
      request = method.new(endpoint)
      request['PRIVATE-TOKEN'] = instance[:access_token]
      instance[:http].request(request)
    end
    
    $target_user_ids = {}
    def lookup_user(instance, username)
      unless $target_user_ids[username]
        user = JSON.parse(api_request(instance, Net::HTTP::Get, "/api/v4/users?username=#{username}").body).first
        if user
          $target_user_ids[username] = user['id']
        else
          puts "Could not find user @#{username} on #{instance[:uri]}!"
        end
      end
    
      $target_user_ids[username]
    end
    
    namespaces.each do |namespace|
      projects_endpoint = "/api/v4/groups/#{namespace}/projects"
      project_pages = api_request(source_instance, Net::HTTP::Head, projects_endpoint)['X-Total-Pages'].to_i
      project_pages.times do |project_page_index|
        projects = JSON.parse(api_request(source_instance, Net::HTTP::Get, "#{projects_endpoint}?page=#{project_page_index}").body)
        projects.each do |project|
    
          puts "Fixing assignees for Issues in #{project['name_with_namespace']} ..."
    
          issue_pages = api_request(source_instance, Net::HTTP::Head, project['_links']['issues'])['X-Total-Pages'].to_i
          issue_pages.times do |issue_page_index|
            issues = JSON.parse(api_request(source_instance, Net::HTTP::Get, "#{project['_links']['issues']}?page=#{issue_page_index}").body)
            issues.each do |issue|
              puts "Fixing ##{issue['iid']} (#{issue['title']})"
              assignee_ids = issue['assignees'].map {|user| lookup_user(target_instance, user['username'])}.reject {|id| id.nil? }
    
              if assignee_ids.empty?
                puts 'Issue has no assignees!'
                next
              end
    
              puts "Setting assignees to #{assignee_ids}"
              target_endpoint = "/api/v4/projects/#{namespace}%2F#{project['path']}/issues/#{issue['iid']}?assignee_ids=#{assignee_ids.join(',')}"
              response = api_request(target_instance, Net::HTTP::Put, target_endpoint)
              puts "Failed! #{response.body}" unless response.kind_of? Net::HTTPSuccess
            end
          end
    
          puts "Fixing assignees for Merge Requests in #{project['name_with_namespace']} ..."
          
                mr_pages = api_request(source_instance, Net::HTTP::Head, project['_links']['merge_requests'])['X-Total-Pages'].to_i
                mr_pages.times do |mr_page_index|
                  merge_requests = JSON.parse(api_request(source_instance, Net::HTTP::Get, "#{project['_links']['merge_requests']}?page=#{mr_page_index}").body)
                  merge_requests.each do |merge_request|
                    puts "Fixing ##{merge_request['iid']} (#{merge_request['title']})"
                    assignee_id =  lookup_user(target_instance, merge_request['assignee']['username'])
                    
                    if assignee_id.nil?
                      puts 'Merge Request has no assignee!'
                      next
                    end
          
                    puts "Setting assignee to #{assignee_id}"
                    target_endpoint = "/api/v4/projects/#{namespace}%2F#{project['path']}/merge_requests/#{merge_request['iid']}?assignee_id=#{assignee_id}"
                    response = api_request(target_instance, Net::HTTP::Put, target_endpoint)
                    puts "Failed! #{response.body}" unless response.kind_of? Net::HTTPSuccess
                  end
                end
    
        end
      end
    end
  • Author Contributor

    @abuango merge requests should not be affected by this—at least I could not reproduce there. 🤔

  • Uhmmmm, I tried it and the Administrator account on my instance was assigned, despite having the same username on the instance. Also, this only works on a public project (on the Target instance).

  • Author Contributor

    @abuango Oh... sorry... maybe the IMPORT is broken. I only tested the export. 😟

0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment