Created
May 23, 2015 13:35
-
-
Save ivodvb/43544d7de4eb405d160c to your computer and use it in GitHub Desktop.
Github issue export to CSV (Github API V3)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
#usage php github_issue_export ivodvb/repo1 ivodvb/repo2 | |
function msg($msg) { | |
echo $msg . PHP_EOL; | |
} | |
function kill($msg, $success = true) { | |
msg($msg); | |
exit(($success ? 0 : 1)); | |
} | |
if (!isset($argv[1])) { | |
kill('Missing repo name, please provide it as the first parameter.', false); | |
} | |
function getIssues($githubRepoName, $limit = 100, $pageNo = 1) { | |
if (!preg_match('/^[a-z0-9\-.]{0,64}\/[a-z0-9\-.]{0,64}+$/i', $githubRepoName)) { | |
kill(sprintf('Github repository name is of invalid format. Received: %s', $githubRepoName), false); | |
} | |
msg(sprintf('Found Github repo name %s with limit of %d and page no %d. Will try to load it.', $githubRepoName, $limit, $pageNo)); | |
$url = 'https://api.github.com/repos/%s/issues?filter=all&state=all&per_page=%d&page=%d'; | |
$headers = [ | |
'Accept: application/vnd.github.v3+json', | |
'User-Agent: YOUR_USERNAME', | |
'Authorization: token YOUR_TOKEN' | |
]; | |
msg('Sending request...'); | |
$generatedUrl = sprintf($url, $githubRepoName, $limit, $pageNo); | |
msg(sprintf('Generated URL %s', $generatedUrl)); | |
$ch = curl_init($generatedUrl); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
$response = curl_exec($ch); | |
$responseInfo = curl_getinfo($ch); | |
curl_close($ch); | |
msg('Received response, now evaluating it.'); | |
if ($responseInfo['http_code'] != 200) { | |
kill(sprintf('Oops.. Something went wrong with accessing the Github API.' . | |
'Received HTTP status code %d.' . PHP_EOL . | |
'Response data: ' . PHP_EOL . ' %s', $responseInfo['http_code'], $response), false); | |
} | |
msg(sprintf('HTTP request succeed (status code 200 and content length %d) without errors, will now validate and try to parse data.', strlen($response))); | |
$issues = json_decode($response, true); | |
if (null === $issues) { | |
kill(sprintf('Failed to parse Github API response as JSON although we\'ve received a 200 OK HTTP header. ' . PHP_EOL . | |
'Response: ' . PHP_EOL . '%s', $response), false); | |
} | |
msg(sprintf('Found %d issues.', count($issues))); | |
foreach ($issues as $key => $issue) { | |
$issues[$key]['repository_name'] = $githubRepoName; | |
} | |
return $issues; | |
} | |
$githubRepoName = $argv[1]; | |
msg(sprintf('Found repository name %s.', $githubRepoName)); | |
// We allow multiple repositories | |
$repositoryNames = [$githubRepoName]; | |
$paramNo = 2; | |
while(isset($argv[$paramNo]) && !empty($argv[$paramNo])) { | |
$githubRepoName = $argv[$paramNo]; | |
msg(sprintf('Found another repository name: %s.', $githubRepoName)); | |
$repositoryNames[] = $githubRepoName; | |
$paramNo += 1; | |
} | |
msg(''); | |
$issues = []; | |
foreach ($repositoryNames as $githubRepoName) { | |
$pageNo = 1; | |
$newIssues = getIssues($githubRepoName, 100, $pageNo); | |
$issues = array_merge($issues, $newIssues); | |
while(count($newIssues) == 100) { | |
$pageNo += 1; | |
$newIssues = getIssues($githubRepoName, 100, $pageNo); | |
$issues = array_merge($issues, $newIssues); | |
} | |
msg(''); | |
} | |
$filename = sprintf('%d-issues.csv', time()); | |
$fh = fopen($filename, 'w+'); | |
fputcsv($fh, [ | |
'repository', | |
'creator', | |
'number', | |
'title', | |
'state', | |
'assignee', | |
'milestone', | |
'labels', | |
'closed_at', | |
'url' | |
]); | |
foreach ($issues as $issue) { | |
$assignee = ''; | |
if (!empty($issue['assignee'])) { | |
$assignee = $issue['assignee']['login']; | |
} | |
$milestone = ''; | |
if (!empty($issue['milestone'])) { | |
$issueDueOnDatetime = new Datetime($issue['milestone']['due_on']); | |
$milestone = $issue['milestone']['title'] . ' - ' . $issueDueOnDatetime->format('d-m-y H:i:s'); | |
} | |
$labels = ''; | |
if (!empty($issue['labels'])) { | |
foreach ($issue['labels'] as $label) { | |
if (!empty($labels)) { | |
$labels .= ', '; | |
} | |
$labels .= $label['name']; | |
} | |
} | |
fputcsv($fh, [ | |
$issue['repository_name'], // added it manually by a local function | |
$issue['user']['login'], | |
$issue['number'], | |
$issue['title'], | |
$issue['state'], | |
$assignee, | |
$milestone, | |
$labels, | |
$issue['closed_at'], | |
$issue['url'] | |
]); | |
} | |
kill(sprintf('Written %d issues to CSV file ' . PHP_EOL . '%s', count($issues), $filename)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment