Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Exports Github issues to CSV so it can be imported into Jira
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
@henare

This comment has been minimized.

Copy link
Owner Author

@henare henare commented Jul 26, 2011

The voodoo with importing comments with dates and usernames intact in Jira is to save your import configuration then add this line to it:

"settings.advanced.mapper.comment" : "com.atlassian.jira.plugins.importer.imports.csv.mappers.PvcsComment"
@tkarpinski

This comment has been minimized.

Copy link

@tkarpinski tkarpinski commented Apr 12, 2012

Thanks for this - I took the code and the octokit gem and made a version using the v3 github API here. I didn't re-implement comments, although that'd be relatively trivial to do.

@henare

This comment has been minimized.

Copy link
Owner Author

@henare henare commented Apr 12, 2012

Very cool, thanks for letting me know @tkarpinski

Yeah the comments import in Jira is a bitch. As you can see from the script you need a column for every comment and you have to format them in a special way so that the comment user and date is picked up (WTF?).

@kylecordes

This comment has been minimized.

Copy link

@kylecordes kylecordes commented Nov 8, 2012

This code was very helpful to me in understanding what data to produce for JIRA. But it didn't handle enough of the data for what I needed, I ended up writing a somewhat more complex exporter (in Clojure). In addition to comments, I bring along events (open/closed), maps usernames, and carries over milestones and labels.

http://kylecordes.com/2012/github-issues-export-jira

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment