Skip to content

Instantly share code, notes, and snippets.

@ivodvb
Created May 23, 2015 13:35
Show Gist options
  • Save ivodvb/43544d7de4eb405d160c to your computer and use it in GitHub Desktop.
Save ivodvb/43544d7de4eb405d160c to your computer and use it in GitHub Desktop.
Github issue export to CSV (Github API V3)
<?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