Skip to content

Instantly share code, notes, and snippets.

@jussi-kalliokoski
Created December 25, 2012 21:54
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jussi-kalliokoski/4375613 to your computer and use it in GitHub Desktop.
Save jussi-kalliokoski/4375613 to your computer and use it in GitHub Desktop.
A script to export bugzilla's bugs to github's issues.
request = require 'request'
Restzilla = require 'restzilla'
BUGZILLA_URL = 'https://www.w3.org/Bugs/Public/'
BURL = 'http://localhost:8000/AudioWG/MIDI%20API/'
GH_USER = 'jussi-kalliokoski'
GH_REPO = 'webmidi-issues'
GH_URL = 'https://api.github.com/repos/' + GH_USER + '/' + GH_REPO + '/issues'
GH_AUTH =
username: 'octocat'
password: 'secret'
# create a RESTful wrapper for Bugzilla
server = Restzilla
baseURL: BUGZILLA_URL
server.listen 8000
gh = (method, url, body, callback) ->
options =
method: method
headers:
authorization: 'Basic ' + Buffer(GH_AUTH.username + ':' + GH_AUTH.password).toString('base64')
body: JSON.stringify(body)
url: GH_URL + url
request options, (e, res, body) ->
callback e, res, JSON.parse(body)
createIssue = (issue, callback) ->
gh 'POST', '', issue, (e, res, body) ->
return callback(e, null) if e
return callback(Error('Error creating issue (' + res.statusCode + ')\n' + JSON.stringify(body)), null) if res.statusCode isnt 201
callback null, body
createComment = (issueNumber, comment, callback) ->
gh 'POST', '/' + issueNumber + '/comments', comment, (e, res, body) ->
return callback(e, null) if e
return callback(Error('Error creating comment (' + res.statusCode + ')\n' + JSON.stringify(body)), null) if res.statusCode isnt 201
callback null, body
closeIssue = (issueNumber, callback) ->
body =
state: 'closed'
gh 'PATCH', '/' + issueNumber, body, (e, res, body) ->
return callback(e, null) if e
return callback(Error('Error closing issue ' + issueNumber + ' (' + res.statusCode + ')\n' + JSON.stringify(body)), null) if res.statusCode isnt 200
callback null, body
start = ->
request BURL, (e, res, body) ->
throw e if e
issues = JSON.parse(body)
c = issues.length
for issue in issues
processIssue issue, ->
if not --c
process.nextTick finish
convertBugToIssue = (bug) ->
body = '> Originally reported on W3C Bugzilla [ISSUE-' + bug.number + '](' + BUGZILLA_URL + 'show_bug.cgi?id=' + bug.number + ')'
body += ' ' + (new Date(bug.created_at)).toGMTString() + '\n'
body += '> Reported by ' + bug.reporter + '\n'
body += '> Assigned to ' + bug.assignee + '\n'
body += '\n' + bug.body
issue =
user: GH_USER
repo: GH_REPO
title: bug.title
body: body
labels: bug.status.split(' ').filter (v) -> !~['NEW'].indexOf(v)
processIssue = (id, done) ->
request BURL + id, (e, res, body) ->
throw e if e
bug = JSON.parse body
issue = convertBugToIssue bug
createIssue issue, (e, ghissue) ->
throw e if e
console.error 'Created issue #' + ghissue.number, ghissue.title
closeIfNeeded = ->
closed = /^(RESOLVED|CLOSED)/.test(bug.status)
return done() if not closed
closeIssue ghissue.number, (e, body) ->
throw e if e
console.error 'Closed issue #' + ghissue.number, ghissue.title, '(Was ' + bug.status + ')'
done()
return closeIfNeeded() if not bug.comments
request BURL + id + '/comments', (e, res, body) ->
throw e if e
comments = JSON.parse(body)
ids = []
cont = (id) ->
ids.push id if id
comment = comments.shift()
if not comment
console.error 'Populated ' + ids.length + ' comments for issue #' + ghissue.number, ghissue.title
return closeIfNeeded()
comment.bugURL = BUGZILLA_URL + 'show_bug.cgi?id=' + bug.number + '#' + comment.number
processComment(comment, ghissue, ids, cont)
cont()
convertCommentToGHComment = (comment, idlist) ->
body = '> [Original comment](' + comment.bugURL + ') by ' + comment.user + ' on W3C Bugzilla.'
body += ' ' + (new Date(comment.created_at)).toGMTString() + '\n'
body += '\n'
body += comment.body.replace /\(In reply to comment #(\d+)\)/g, (all, num) ->
num -= 1
return all if not idlist[num]
return '(In reply to [comment #' + (num + 1) + '](#issuecomment-' + idlist[num] + '))'
comm =
body: body
processComment = (comment, ghissue, idlist, done) ->
body = convertCommentToGHComment comment, idlist
createComment ghissue.number, body, (e, ghcomment) ->
throw e if e
done(ghcomment.id)
finish = ->
console.log 'Done'
process.exit()
start()
@jussi-kalliokoski
Copy link
Author

Obviously, you'll have to supply valid credentials instead of octocat.

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