class IssueMigrator

Attributes

access_token[RW]

attr_accessor :issues, :client, :target_repo, :source_repo

client[RW]

attr_accessor :issues, :client, :target_repo, :source_repo

ilist[RW]

attr_accessor :issues, :client, :target_repo, :source_repo

issues[RW]

attr_accessor :issues, :client, :target_repo, :source_repo

itype[RW]

attr_accessor :issues, :client, :target_repo, :source_repo

source_repo[RW]

attr_accessor :issues, :client, :target_repo, :source_repo

target_repo[RW]

attr_accessor :issues, :client, :target_repo, :source_repo

Public Class Methods

new(access_token, source_repo, target_repo) click to toggle source

curl -v -H “Authorization: token <MY-40-CHAR-TOKEN>” \

-H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/E3V3A/gh-missue/issues
# File bin/missue.rb, line 153
def initialize(access_token, source_repo, target_repo)
    @client = Octokit::Client.new( 
        :access_token => access_token,
        :accept       => 'application/vnd.github.v3+json',
        :headers      => { "Authorization" => "token " + access_token },
        # :headers => { "X-GitHub-OTP" => "<your 2FA token>" }

        # // Personal OAuth2 Access Token
        #:access_token => "YOUR_40_CHAR_OATH2_TOKEN"

        # // OAuth2 App Credentials  (DEPRECATED!)
        # NEW use:
        # curl -u my_client_id:my_client_secret https://api.github.com/user/repos
        #:client_id     => "<YOUR_20_CHAR_OATH2_ID>",
        #:client_secret => "<YOUR_40_CHAR_OATH2_SECRET>"
        
        per_page: 100 
    )
    user = client.user
    user.login
    @source_repo = source_repo
    @target_repo = target_repo
    @itype = itype
    @ilist = ilist      # 2022-01-27 18:48:35
end

Public Instance Methods

create_target_labels() click to toggle source
# File bin/missue.rb, line 236
def create_target_labels
    @client.auto_paginate = true
    @source_labels = @client.labels(@source_repo.freeze, accept: 'application/vnd.github.symmetra-preview+json')
    # @target_labels = @client.add_label(@target_repo.freeze, accept: 'application/vnd.github.symmetra-preview+json')
    puts "Found #{@source_labels.size} issue labels in <source_repo>:"
    puts "Copying labels..."
    tlabel = "" # nil
    @source_labels.each do |lbl|
        #puts "[#{lbl.color}]  " + "#{lbl.name}".ljust(20) + ": #{lbl.description}"
        puts "[#{label.color}]  " + color_box + "#{label.name}".ljust(20) + ": #{label.description}"
        #tlabel = {"name": lbl.name, "description": lbl.description, "color": lbl.color}
        #tlabel = {lbl.name, lbl.color, description: lbl.description}
        #lab = client.add_label(@target_repo.freeze, accept: 'application/vnd.github.symmetra-preview+json', tlabel)
        lab = client.add_label(@target_repo.freeze, lbl.name, lbl.color, accept: 'application/vnd.github.symmetra-preview+json', description: lbl.description)
        sleep(2)
    end
    puts "done."
end
getToken() click to toggle source
# File bin/missue.rb, line 147
def getToken
    access_token = "#{ENV['GITHUB_OAUTH_TOKEN']}" # @access_token ???
end
get_source_comments(source_issue) click to toggle source
# File bin/missue.rb, line 292
def get_source_comments(source_issue)
    comments = []
    source_comments = @client.issue_comments(@source_repo, source_issue.number)
    source_comments.each do |cmt|
        comments << cmt.body
    end
    comments
end
get_source_labels(source_issue) click to toggle source
# File bin/missue.rb, line 283
def get_source_labels(source_issue)
    labels = []
    source_issue.labels.each do |lbl|
        labels << {"name": lbl.name, "description": lbl.description, "color": lbl.color}
    end
    #puts "Labels: #{labels}"
    labels
end
hex2rgb(hex) click to toggle source
# File bin/missue.rb, line 141
def hex2rgb(hex)
    # Usage: print hex2rgb("d73a4a") - prints a RGB colored box from hex
    r,g,b = hex.match(/^(..)(..)(..)$/).captures.map(&:hex)
    s = "\e[48;2;#{r};#{g};#{b}m  \e[0m"
end
list_source_issues(itype) click to toggle source
# File bin/missue.rb, line 216
def list_source_issues(itype)
    pull_source_issues(itype)
    @issues.each do |source_issue|
        puts "[#{source_issue.number}]".ljust(10) + "#{source_issue.title}"
    end
    puts
end
list_source_labels() click to toggle source
# File bin/missue.rb, line 224
def list_source_labels
    @client.auto_paginate = true
    @labels = @client.labels(@source_repo.freeze, accept: 'application/vnd.github.symmetra-preview+json')
    puts "Found #{@labels.size} issue labels:"
    # ToDo: check and handle length (in case > 20)
    @labels.each do |label|
        color_box = hex2rgb("#{label.color}") + "  "
        puts "[#{label.color}]  " + color_box + "#{label.name}".ljust(20) + ": #{label.description}"
    end
    puts
end
pull_source_issues(itype, ilist = nil) click to toggle source
# File bin/missue.rb, line 179
def pull_source_issues(itype, ilist = nil)
    @client.auto_paginate = true

    puts "\n  <itype>: #{itype}"
    puts "  <ilist>: #{ilist}\n"

    # itype is a constant, while ilist is a list, so we need to iterate
    # The issue list:   <ilist>: "1,2,5-7,19"
    if itype
        @issues = @client.issues(@source_repo, :state => itype)     # The issue type:   <itype>: [open/closed/all]
    elsif ilist
        #@issues = @client.issues(@source_repo, :state => 'all')
        
        #@issues.each do |source_issue|
        #    print "Processing issue: #{source_issue.number}  (#{n}/#{issues.size})\r"
        #    if !source_issue.key?(:pull_request) || source_issue.pull_request.empty?
        #       #
        #    end
        #end

        puts
        my_array = []
        ilist.each do |i|
            puts "Adding issue [#]: #{i} \t from: #{@source_repo}\n"
            my_array.push(@client.issue(@source_repo.freeze, "#{i}", accept: 'application/vnd.github.v3+json', :state => 'all'))
            #@issues.push(@client.issue(@source_repo.freeze, "#{i}", accept: 'application/vnd.github.v3+json', :state => 'all'))
        end
        @issues = my_array
    end
    
    opa = "#{@issues}".split(',').join(",\n")
    puts "\n\n#{opa}\n\n" if $debug
    
    # ToDo: "itype" should be [issue, pr] and "istat" should be [open,closed,all].
    puts "\nFound #{issues.size} issues of status: #{itype}\n"
end
push_comments(target_issue, source_comments) click to toggle source
# File bin/missue.rb, line 301
def push_comments(target_issue, source_comments)
    source_comments.each do |cmt|
        @client.add_comment(@target_repo, target_issue.number, cmt)
    end
end
push_issues() click to toggle source
# File bin/missue.rb, line 255
def push_issues
    @issues.reverse!
    n = 0
    @issues.each do |source_issue|
        n += 1
        print "Pushing issue: #{source_issue.number}  (#{n}/#{issues.size})\r"
        source_labels = get_source_labels(source_issue)
        source_comments = get_source_comments(source_issue)

        # Only push if not a PR || empy         ??? 2022-01-27 19:42:37
        if !source_issue.key?(:pull_request) || source_issue.pull_request.empty?

            # PR#2
            issue_body = "*Originally created by @#{source_issue.user[:login]} (#{source_issue.html_url}):*\n\n#{source_issue.body}"
            target_issue = @client.create_issue(@target_repo, source_issue.title, issue_body, {labels: source_labels})

            push_comments(target_issue, source_comments) unless source_comments.empty?
            
            # Close target issue IF it was already closed!
            # ToDo: -k switch!
            @client.close_issue(@target_repo, target_issue.number) if source_issue.state === 'closed'
        end
        # We need to set a rate limit, even for OA2, it is 0.5 [req/sec]
        sleep(5) if ( issues.size > 1 ) # [sec]
    end
    puts "\n"
end