for name in (trac_labels - gh_labels): try: color = trac_label_colors[trac_label_types[name]][name] except KeyError: color = 'e8e8e8' github.labels(data={ 'name': name, 'color': color, }) # == Milestone Migration == # Get any existing GitHub milestones so we can merge Trac into them. # We need to reference them by numeric ID in tickets. logging.info("Getting existing GitHub milestones...") milestone_id = {} for m in github.milestones(): milestone_id[m['title']] = m['number'] logging.debug("milestone (open) title={0}".format(m['title'])) # API returns only 'open' issues by default, have to ask for closed like: # curl -u 'USER:PASS' https://api.github.com/repos/USERNAME/REPONAME/milestones?state=closed for m in github.milestones(query='state=closed'): milestone_id[m['title']] = m['number'] logging.debug("milestone (closed) title={0}".format(m['title'])) # We have no way to set the milestone closed date in GitHub. # The 'due' and 'completed' are long ints representing datetimes. logging.info("Migrating Trac milestones to GitHub...") milestones = trac.sql('SELECT name, description, due, completed FROM milestone') for name, description, due, completed in milestones: name = name.strip() if name in milestone_id:
for name, description, due, completed in milestones: name = name.strip() logging.debug("milestone name=%s due=%s completed=%s" % (name, due, completed)) if name and name not in milestone_id: if completed: state = 'closed' else: state = 'open' milestone = {'title': name, 'state': state, 'description': description, } if due: milestone['due_on'] = epoch_to_iso(due) logging.debug("milestone: %s" % milestone) gh_milestone = github.milestones(id_ = max(chain([0], milestone_id.values())) + 1, data=milestone) milestone_id[name] = gh_milestone['number'] # Copy Trac tickets to GitHub issues, keyed to milestones above tickets = trac.sql('SELECT id, summary, description , owner, milestone, component, status, time, changetime, reporter, keywords, severity, priority, resolution, type FROM ticket ORDER BY id') # LIMIT 5 for tid, summary, description, owner, milestone, component, status, \ created_at, updated_at, reporter, keywords, severity, priority, resolution, type in tickets: if options.component and options.component != component: continue logging.info("Ticket %d: %s" % (tid, summary)) if description: description = description.strip() if milestone: milestone = milestone.strip() issue = {'title': summary}