Skip to content

Instantly share code, notes, and snippets.

@ralphje
Created March 7, 2013 10:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ralphje/5106949 to your computer and use it in GitHub Desktop.
Save ralphje/5106949 to your computer and use it in GitHub Desktop.
Migrating issues from Redmine to GitHub
import csv
import datetime
import feedparser # pip install feedparser
import html2text # pip install html2text
from pygithub3 import Github # pip install pygithub3
# USAGE: Create a csv with all columns from Redmine and fetch
# your API key from Redmine. Then use the code below to match
# properties of the csv with properties of your GitHub issues.
# Note: remove the first line of the exported CSV.
REDMINE_CSV = 'ma.csv'
REDMINE_APIKEY = 'your-api-key-from-redmine'
REDMINE_URL = 'https://redmine.company.com/' # with slash
GITHUB_USER = 'TheGitHubUser'
GITHUB_REPO = 'the-repo'
github = Github(login='TheUserOwningAllIssues', password='thepassword')
# In this case, I used a mapping of milestones to numbers, but you
# may also be able to do this yourself.
milestones = { '0.0.1': 1
}
# My fields were:
# #,Project,Tracker,Parent task,Status,Priority,Subject,
# Author,Assignee,Updated,Category,Target version,Start date,
# Due date,Estimated time,Spent time,% Done,Created,Related issues,
# Resolution,URL with error,Private,Description
with open(REDMINE_CSV, 'rb') as csvfile:
issues = csv.reader(csvfile)
for issue in issues:
# Mapping from csv to names starts here.
r_ticket_id = issue[0]
r_title = issue[6].decode('iso-8859-1')
r_milestone = issue[11]
r_status = issue[4]
r_tracker = issue[2]
r_resolution = issue[19]
r_description = issue[22].decode('iso-8859-1')
r_author = issue[7].decode('iso-8859-1')
r_created = issue[17]
# translation to GitHub
print r_ticket_id, r_title, r_milestone, r_status, r_tracker, r_resolution
title = r_title
body = u'%s\n\n_Originally placed by **%s** at **%s**, migrated from [Redmine ticket #%s](%sissues/%s) redmine-%s_' % \
(r_description, r_author, r_created, r_ticket_id, REDMINE_URL, r_ticket_id, r_ticket_id)
labels = []
if r_tracker == 'Feature':
labels.append('enhancement')
if r_tracker == 'Bug':
labels.append('bug')
if r_tracker == 'Support':
labels.append('question')
if r_resolution == "Won't fix":
labels.append('wontfix')
if r_resolution == "Duplicate":
labels.append('duplicate')
if r_resolution in ("Can't reproduce", 'Invalid', 'No feedback'):
labels.append('invalid')
if r_status in ('Closed','Rejected'):
state = 'closed'
else:
state = 'open'
if r_milestone in milestones:
milestone = milestones[r_milestone]
else:
milestone = None
print title, body, labels, state
issue = github.issues.create({'title': title, 'body': body, 'milestone': milestone, 'labels': labels}, GITHUB_USER, GITHUB_REPO)
if state == 'closed':
github.issues.update(issue.number, {'state': state}, GITHUB_USER, GITHUB_REPO)
comments = feedparser.parse('%sissues/%s.atom?key=%s' % (REDMINE_URL, r_ticket_id, REDMINE_APIKEY))
for comment in comments.entries:
author = comment.author_detail.name
posted_at = datetime.datetime(*comment.updated_parsed[:6]).strftime('%d %B %Y %H:%M')
content = html2text.html2text(comment.summary)
body = u"_Originally placed by **%s** at **%s**_:\n\n%s" % (author, posted_at, content)
print '%s\n------' % body
github.issues.comments.create(issue.number, body, GITHUB_USER, GITHUB_REPO)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment