Skip to content

Instantly share code, notes, and snippets.

@revmischa
Created April 26, 2011 00:17
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 revmischa/941527 to your computer and use it in GitHub Desktop.
Save revmischa/941527 to your computer and use it in GitHub Desktop.
Migrate pivotal tracker stories to github issues
#!/usr/bin/env perl
# Migrate PT stories to GitHub issues
use Moose;
use WWW::PivotalTracker qw/
add_note
add_story
all_stories
delete_story
project_details
show_story
stories_for_filter
update_story
/;
use Net::GitHub;
use Data::Dumper;
use XML::Simple;
my ($pt_token, $proj_id, $gh_token, $gh_owner, $gh_login, $gh_repo) = @ARGV;
die "Usage: $0 \$PT_TOKEN \$PT_PROJECT_ID \$GITHUB_TOKEN \$GITHUB_OWNER \$GITHUB_LOGIN \$GITHUB_REPO"
unless $pt_token && $proj_id && $gh_token && $gh_owner && $gh_login && $gh_repo;
my $gh = Net::GitHub->new(
owner => $gh_owner, repo => $gh_repo,
login => $gh_login, token => $gh_token,
) or die;
my $open_issues = $gh->issue->list('open');
my $closed_issues = $gh->issue->list('closed');
my @all_issues = (@$open_issues, @$closed_issues);
my $pt_xml = `curl -q -H "X-TrackerToken: $pt_token" -X GET http://www.pivotaltracker.com/services/v3/projects/$proj_id/stories`;
my $pt = XMLin($pt_xml);
my $stories = $pt->{story};
my $created = 0;
while (my ($story_name, $story) = each %$stories) {
# does story already exist in github?
next if grep { $_->{title} eq $story_name } @all_issues;
my $state = issue_state($story->{current_state});
my $issue = $gh->issue->open($story_name, $story->{description});
$gh->issue->close($issue->{number}) if $state eq 'closed';
$created++;
select undef, undef, undef, 0.5;
}
print "Created $created issues\n";
sub issue_state {
my ($pt_state) = @_;
my $state = {
'accepted' => 'closed',
'unscheduled' => 'open',
'started' => 'open',
'finished' => 'closed',
'delivered' => 'closed',
'rejected' => 'open',
}->{$pt_state};
warn "unknown state $pt_state" unless $state;
return $state || 'open';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment