Skip to content

Instantly share code, notes, and snippets.

Revisions

  1. @kevinpschaaf kevinpschaaf revised this gist Jun 20, 2012. 2 changed files with 138 additions and 94 deletions.
    94 changes: 0 additions & 94 deletions github_issues_to_csv.rb
    Original file line number Diff line number Diff line change
    @@ -1,94 +0,0 @@
    require 'octokit'
    require 'csv'
    require 'date'
    # Github credentials to access your private project
    USERNAME="USER_NAME"
    PASSWORD="SEKRIT"

    # Project you want to export issues from
    USER="REPO_OWNER"
    PROJECT="REPO_NAME"

    # Your local timezone offset to convert times
    TIMEZONE_OFFSET="-4"

    client = Octokit::Client.new(:login => USERNAME, :password => PASSWORD)

    csv = CSV.new(File.open(File.dirname(__FILE__) + "/issues3.csv", 'w'))

    puts "Initialising CSV file..."
    #CSV Headers
    header = [
    "Summary",
    "Description",
    "Date created",
    "Date modified",
    "Issue type",
    "Milestone",
    "Priority",
    "Status",
    "Reporter"
    ]
    # We need to add a column for each comment, so this dictates how many comments for each issue you want to support
    #20.times { header << "Comments" }
    csv << header

    puts "Getting issues from Github..."
    temp_issues = []
    issues = []
    page = 0
    begin
    page = page +1
    temp_issues = client.list_issues("#{USER}/#{PROJECT}", :state => "closed", :page => page)
    issues = issues + temp_issues;
    end while not temp_issues.empty?
    temp_issues = []
    page = 0
    begin
    page = page +1
    temp_issues = client.list_issues("#{USER}/#{PROJECT}", :state => "open", :page => page)
    issues = issues + temp_issues;
    end while not temp_issues.empty?


    puts "Processing #{issues.size} issues..."
    issues.each do |issue|
    puts "Processing issue #{issue['number']}..."
    # Work out the type based on our existing labels
    case
    when issue['labels'].to_s =~ /Bug/i
    type = "Bug"
    when issue['labels'].to_s =~ /Feature/i
    type = "New feature"
    when issue['labels'].to_s =~ /Task/i
    type = "Task"
    end

    # Work out the priority based on our existing labels
    case
    when issue['labels'].to_s =~ /HIGH/i
    priority = "Critical"
    when issue['labels'].to_s =~ /MEDIUM/i
    priority = "Major"
    when issue['labels'].to_s =~ /LOW/i
    priority = "Minor"
    end
    milestone = issue['milestone'] || "None"
    if (milestone != "None")
    milestone = milestone['title']
    end

    # Needs to match the header order above, date format are based on Jira default
    row = [
    issue['title'],
    issue['body'],
    DateTime.parse(issue['created_at']).new_offset(TIMEZONE_OFFSET).strftime("%d/%b/%y %l:%M %p"),
    DateTime.parse(issue['updated_at']).new_offset(TIMEZONE_OFFSET).strftime("%d/%b/%y %l:%M %p"),
    type,
    milestone,
    priority,
    issue['state'],
    issue['user']['login']
    ]
    csv << row
    end
    138 changes: 138 additions & 0 deletions github_issues_to_csv_v3.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,138 @@
    require 'octokit'
    require 'csv'
    require 'date'

    # Description:
    # Exports Github issues from one or more repos into CSV file formatted for import into JIRA
    # Note: By default, all Github comments will be assigned to the JIRA admin, appended with
    # a note indicating the Github user who added the comment (since you may not have JIRA users
    # created for all your Github users, especially if it is a public/open-source project:
    #
    # Administrator added a comment - 13/Jun/12 5:13 PM
    # Imported from Github issue xyz-123, originally reported by ubercoder42
    #
    # Administrator added a comment - 12/Jun/12 10:00 AM
    # Github comment from ubercoder42: [Text from first comment here...]

    # Usage:
    # > ruby github_issues_to_csv_v3.rb <JIRA admin username> <Github username> <Github password> <Github project/user> <repo 1> .. <repo n>

    # Your local timezone offset to convert times -- CHANGE THESE TO MATCH YOUR SETTINGS
    TIMEZONE_OFFSET="-8"
    COMMENT_DATE_FORMAT="%m/%d/%Y %T"

    OTHER_DATE_FORMAT="%-m/%-d/%y %H:%M" # Don't change this; Comments must be in this format
    COMMENT_NOW = DateTime.now.new_offset(TIMEZONE_OFFSET).strftime(COMMENT_DATE_FORMAT)
    # Grab command line args
    JIRA_ADMIN=ARGV.shift
    USERNAME=ARGV.shift
    PASSWORD=ARGV.shift
    USER=ARGV.shift


    client = Octokit::Client.new(:login => USERNAME, :password => PASSWORD)

    csv = CSV.new(File.open(File.dirname(__FILE__) + "/issues_#{USER}.csv", 'w'), :force_quotes=>true)

    puts "Initialising CSV file..."
    #CSV Headers
    header = [
    "Summary",
    "Description",
    "Date created",
    "Date modified",
    "Issue type",
    "Milestone",
    "Priority",
    "Status",
    "Reporter",
    "Github repo",
    "Github number"
    ]
    # We need to add a column for each comment, so this dictates how many comments for each issue you want to support
    20.times { header << "Comments" }
    csv << header

    ARGV.each do |project|
    puts "Getting issues from #{project}..."
    temp_issues = []
    issues = []
    page = 0
    begin
    page = page +1
    temp_issues = client.list_issues("#{USER}/#{project}", :state => "closed", :page => page)
    issues = issues + temp_issues;
    end while not temp_issues.empty?
    temp_issues = []
    page = 0
    begin
    page = page +1
    temp_issues = client.list_issues("#{USER}/#{project}", :state => "open", :page => page)
    issues = issues + temp_issues;
    end while not temp_issues.empty?


    puts "Processing #{issues.size} issues..."
    issues.each do |issue|
    puts "Processing issue #{project}-#{issue['number']}..."
    # Work out the type based on our existing labels
    case
    when issue['labels'].to_s =~ /Bug/i
    type = "Bug"
    when issue['labels'].to_s =~ /Feature/i
    type = "New feature"
    when issue['labels'].to_s =~ /Task/i
    type = "Task"
    end

    # Work out the priority based on our existing labels
    case
    when issue['labels'].to_s =~ /HIGH/i
    priority = "Critical"
    when issue['labels'].to_s =~ /MEDIUM/i
    priority = "Major"
    when issue['labels'].to_s =~ /LOW/i
    priority = "Minor"
    end
    milestone = issue['milestone'] || "None"
    if (milestone != "None")
    milestone = milestone['title']
    end

    # Needs to match the header order above
    row = [
    issue['title'],
    issue['body'],
    DateTime.parse(issue['created_at']).new_offset(TIMEZONE_OFFSET).strftime(OTHER_DATE_FORMAT),
    DateTime.parse(issue['updated_at']).new_offset(TIMEZONE_OFFSET).strftime(OTHER_DATE_FORMAT),
    type,
    milestone,
    priority,
    issue['state'],
    issue['user']['login'],
    project,
    "#{project}-#{issue['number']}"
    ]
    row << "#{COMMENT_NOW}; #{JIRA_ADMIN}; Imported from Github issue #{project}-#{issue['number']}, originally reported by #{issue['user']['login']}"
    if issue['comments'] > 0
    puts "Getting #{issue['comments']} comments for issue #{project}-#{issue['number']} from Github..."
    # Get the comments
    comments = client.issue_comments("#{USER}/#{project}", issue['number'])

    comments.each do |c|
    # Date format needs to match hard coded format in the Jira importer
    comment_time = DateTime.parse(c['created_at']).new_offset(TIMEZONE_OFFSET).strftime(COMMENT_DATE_FORMAT)

    # Map usernames for the comments importer. As is, this will assign all comments to
    # JIRA admin user -- use the commented version if you want to use the Github username...
    comment_user = JIRA_ADMIN # c['user']['login']

    # Put the comment in a format Jira can parse
    comment = "#{comment_time}; #{comment_user}; Github comment from #{c['user']['login']}: #{c['body']}"

    row << comment
    end
    end
    csv << row
    end
    end
  2. Tod Karpinski revised this gist Apr 16, 2012. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions github_issues_to_csv.rb
    Original file line number Diff line number Diff line change
    @@ -24,6 +24,7 @@
    "Date created",
    "Date modified",
    "Issue type",
    "Milestone",
    "Priority",
    "Status",
    "Reporter"
    @@ -72,6 +73,10 @@
    when issue['labels'].to_s =~ /LOW/i
    priority = "Minor"
    end
    milestone = issue['milestone'] || "None"
    if (milestone != "None")
    milestone = milestone['title']
    end

    # Needs to match the header order above, date format are based on Jira default
    row = [
    @@ -80,6 +85,7 @@
    DateTime.parse(issue['created_at']).new_offset(TIMEZONE_OFFSET).strftime("%d/%b/%y %l:%M %p"),
    DateTime.parse(issue['updated_at']).new_offset(TIMEZONE_OFFSET).strftime("%d/%b/%y %l:%M %p"),
    type,
    milestone,
    priority,
    issue['state'],
    issue['user']['login']
  3. @tkarpinski tkarpinski revised this gist Apr 12, 2012. 1 changed file with 31 additions and 48 deletions.
    79 changes: 31 additions & 48 deletions github_issues_to_csv.rb
    Original file line number Diff line number Diff line change
    @@ -1,25 +1,23 @@
    require 'json'
    require 'open-uri'
    require 'octokit'
    require 'csv'
    require 'date'

    # Github credentials to access your private project
    USERNAME="myusername"
    PASSWORD="mypassword"
    USERNAME="USER_NAME"
    PASSWORD="SEKRIT"

    # Project you want to export issues from
    USER="someuser"
    PROJECT="someproject"
    USER="REPO_OWNER"
    PROJECT="REPO_NAME"

    # Your local timezone offset to convert times
    TIMEZONE_OFFSET="+10"
    TIMEZONE_OFFSET="-4"

    BASE_URL="https://github.com/api/v2/json/issues"
    client = Octokit::Client.new(:login => USERNAME, :password => PASSWORD)

    csv = CSV.new(File.open(File.dirname(__FILE__) + "/issues.csv", 'w'))
    csv = CSV.new(File.open(File.dirname(__FILE__) + "/issues3.csv", 'w'))

    puts "Initialising CSV file..."
    # CSV Headers
    #CSV Headers
    header = [
    "Summary",
    "Description",
    @@ -31,17 +29,29 @@
    "Reporter"
    ]
    # We need to add a column for each comment, so this dictates how many comments for each issue you want to support
    20.times { header << "Comments" }
    #20.times { header << "Comments" }
    csv << header

    puts "Getting issues from Github..."
    closed_issues = JSON.parse(open("#{BASE_URL}/list/#{USER}/#{PROJECT}/closed", 'r', { :http_basic_authentication => [USERNAME, PASSWORD] }).read)
    open_issues = JSON.parse(open("#{BASE_URL}/list/#{USER}/#{PROJECT}/open", 'r', { :http_basic_authentication => [USERNAME, PASSWORD] }).read)

    all_issues = closed_issues['issues'] + open_issues['issues']

    puts "Processing #{all_issues.size} issues..."
    all_issues.each do |issue|
    temp_issues = []
    issues = []
    page = 0
    begin
    page = page +1
    temp_issues = client.list_issues("#{USER}/#{PROJECT}", :state => "closed", :page => page)
    issues = issues + temp_issues;
    end while not temp_issues.empty?
    temp_issues = []
    page = 0
    begin
    page = page +1
    temp_issues = client.list_issues("#{USER}/#{PROJECT}", :state => "open", :page => page)
    issues = issues + temp_issues;
    end while not temp_issues.empty?


    puts "Processing #{issues.size} issues..."
    issues.each do |issue|
    puts "Processing issue #{issue['number']}..."
    # Work out the type based on our existing labels
    case
    @@ -72,34 +82,7 @@
    type,
    priority,
    issue['state'],
    issue['user']
    issue['user']['login']
    ]

    if issue['comments'] > 0
    puts "Getting #{issue['comments']} comments for issue #{issue['number']} from Github..."
    # Get the comments
    comments = JSON.parse(open("#{BASE_URL}/comments/#{USER}/#{PROJECT}/#{issue['number']}", 'r', { :http_basic_authentication => [USERNAME, PASSWORD] }).read)

    comments['comments'].each do |c|
    # Date format needs to match hard coded format in the Jira importer
    comment_time = DateTime.parse(c['created_at']).new_offset(TIMEZONE_OFFSET).strftime("%m/%d/%y %r")

    # Map usernames for the comments importer
    comment_user = case c['user']
    when "Foo"
    "foo"
    when "baruser"
    "bar"
    when "myfunnyusername"
    "firstname"
    end

    # Put the comment in a format Jira can parse, removing #s as Jira thinks they're comments
    comment = "Comment: #{comment_user}: #{comment_time}: #{c['body'].gsub('#','')}"

    row << comment
    end
    end

    csv << row
    end
    end
  4. @henare henare created this gist Jul 26, 2011.
    105 changes: 105 additions & 0 deletions github_issues_to_csv.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    require 'json'
    require 'open-uri'
    require 'csv'
    require 'date'

    # Github credentials to access your private project
    USERNAME="myusername"
    PASSWORD="mypassword"

    # Project you want to export issues from
    USER="someuser"
    PROJECT="someproject"

    # Your local timezone offset to convert times
    TIMEZONE_OFFSET="+10"

    BASE_URL="https://github.com/api/v2/json/issues"

    csv = CSV.new(File.open(File.dirname(__FILE__) + "/issues.csv", 'w'))

    puts "Initialising CSV file..."
    # CSV Headers
    header = [
    "Summary",
    "Description",
    "Date created",
    "Date modified",
    "Issue type",
    "Priority",
    "Status",
    "Reporter"
    ]
    # We need to add a column for each comment, so this dictates how many comments for each issue you want to support
    20.times { header << "Comments" }
    csv << header

    puts "Getting issues from Github..."
    closed_issues = JSON.parse(open("#{BASE_URL}/list/#{USER}/#{PROJECT}/closed", 'r', { :http_basic_authentication => [USERNAME, PASSWORD] }).read)
    open_issues = JSON.parse(open("#{BASE_URL}/list/#{USER}/#{PROJECT}/open", 'r', { :http_basic_authentication => [USERNAME, PASSWORD] }).read)

    all_issues = closed_issues['issues'] + open_issues['issues']

    puts "Processing #{all_issues.size} issues..."
    all_issues.each do |issue|
    puts "Processing issue #{issue['number']}..."
    # Work out the type based on our existing labels
    case
    when issue['labels'].to_s =~ /Bug/i
    type = "Bug"
    when issue['labels'].to_s =~ /Feature/i
    type = "New feature"
    when issue['labels'].to_s =~ /Task/i
    type = "Task"
    end

    # Work out the priority based on our existing labels
    case
    when issue['labels'].to_s =~ /HIGH/i
    priority = "Critical"
    when issue['labels'].to_s =~ /MEDIUM/i
    priority = "Major"
    when issue['labels'].to_s =~ /LOW/i
    priority = "Minor"
    end

    # Needs to match the header order above, date format are based on Jira default
    row = [
    issue['title'],
    issue['body'],
    DateTime.parse(issue['created_at']).new_offset(TIMEZONE_OFFSET).strftime("%d/%b/%y %l:%M %p"),
    DateTime.parse(issue['updated_at']).new_offset(TIMEZONE_OFFSET).strftime("%d/%b/%y %l:%M %p"),
    type,
    priority,
    issue['state'],
    issue['user']
    ]

    if issue['comments'] > 0
    puts "Getting #{issue['comments']} comments for issue #{issue['number']} from Github..."
    # Get the comments
    comments = JSON.parse(open("#{BASE_URL}/comments/#{USER}/#{PROJECT}/#{issue['number']}", 'r', { :http_basic_authentication => [USERNAME, PASSWORD] }).read)

    comments['comments'].each do |c|
    # Date format needs to match hard coded format in the Jira importer
    comment_time = DateTime.parse(c['created_at']).new_offset(TIMEZONE_OFFSET).strftime("%m/%d/%y %r")

    # Map usernames for the comments importer
    comment_user = case c['user']
    when "Foo"
    "foo"
    when "baruser"
    "bar"
    when "myfunnyusername"
    "firstname"
    end

    # Put the comment in a format Jira can parse, removing #s as Jira thinks they're comments
    comment = "Comment: #{comment_user}: #{comment_time}: #{c['body'].gsub('#','')}"

    row << comment
    end
    end

    csv << row
    end