Created
August 26, 2018 21:32
-
-
Save ryancwalsh/6f61ab68d8331e5810c955fa2700ea11 to your computer and use it in GitHub Desktop.
Export all BitBucket issues to json file
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 | |
/** | |
* EXPORT ALL BITBUCKET ISSUES TO JSON FILE | |
* | |
* I couldn't figure out how to use https://github.com/GrahamCampbell/Laravel-Bitbucket/ so instead am using https://github.com/BitbucketAPI/Client/ directly so that I can export (download) all of my issues from all of my Bitbucket repositories' issue trackers. | |
* | |
* Here are the steps that make it work: | |
* | |
* 1. Visit https://bitbucket.org/account/user/{your_username}/app-passwords | |
* 2. Click "Create app password", and enable "Read" access to all of the following: "Account", "Issues", "Projects", "Repositories". | |
* When I tried granting access to just Issues, I got this misleading error: Symfony\Component\Debug\Exception\FatalThrowableError : strtok() expects parameter 1 to be string, array given | |
* 3. In your .env file, paste the username and password like this: | |
* | |
BITBUCKET_USERNAME=johndoe | |
BITBUCKET_PASSWORD=mmnb54m5nb4mn5b64 | |
* | |
* 4. Create a config/bitbucket.php file that has this: | |
* | |
* return [ | |
'username' => env('BITBUCKET_USERNAME'), | |
'password' => env('BITBUCKET_PASSWORD'), //You will visit https://bitbucket.org/account/user/{your_username}/app-passwords and then paste into your .env file | |
]; | |
* | |
* 5. Run `composer require bitbucket/client` | |
* 6. Now you can use a function like what I wrote for getJsonOfAllIssues() below. | |
* | |
*/ | |
namespace App\Console\Commands; | |
use Bitbucket\Client; | |
use Illuminate\Console\Command; | |
use Storage; | |
class DownloadBitbucketIssues extends Command { | |
const FILENAME = 'issues.json'; | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'downloadBitbucketIssues'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Use the Bitbucket API to download all the issues for backup purposes.'; | |
public function __construct() { | |
parent::__construct(); | |
} | |
public function handle() { | |
$issuesAcrossAllRepos = $this->getJsonOfAllIssues(); | |
Storage::disk('local')->put(self::FILENAME, json_encode($issuesAcrossAllRepos)); | |
$this->info('Saved json of all issues to file: ' . self::FILENAME); | |
//TODO: save file to Amazon S3 too (maybe using https://docs.spatie.be/laravel-backup/v5/introduction) | |
} | |
/** | |
* | |
* @return string | |
*/ | |
public function getJsonOfAllIssues() { | |
$username = config('bitbucket.username'); | |
$c = new Client(); | |
$c->authenticate(Client::AUTH_HTTP_PASSWORD, $username, config('bitbucket.password')); | |
$reposResult = $c->repositories()->users($username)->list(['pagelen' => 100]); //Any account with more than 100 repos will need to edit this code to use pagination instead. | |
$repoNames = []; | |
foreach ($reposResult['values'] as $repoDetails) { | |
$repoNames[] = $repoDetails['name']; | |
} | |
$this->info('Found these repos and will now look to download their issues: ' . json_encode($repoNames)); | |
$namesOfReposWithIssueTracker = []; | |
$issueCounts = []; | |
foreach ($reposResult['values'] as $repoDetails) { | |
$links = $repoDetails['links']; | |
if (isset($links['issues'])) { | |
$namesOfReposWithIssueTracker[] = $repoDetails['name']; | |
$issueCounts[$repoDetails['name']] = 0; | |
} | |
} | |
$issuesAcrossAllRepos = []; | |
foreach ($namesOfReposWithIssueTracker as $repoName) { | |
$issuesForThisRepo = []; | |
$page = 1; | |
do { | |
$resultsForPage = $c->repositories()->users($username)->issues($repoName)->list(['pagelen' => 100, 'page' => $page]); //100 is max: https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Busername%7D/%7Brepo_slug%7D/issues | |
$numResultsOnThisPage = count($resultsForPage['values']); | |
$this->info($repoName . ' page ' . $page . ' has this many results: ' . $numResultsOnThisPage); | |
$issuesForThisRepo = array_merge($issuesForThisRepo, $resultsForPage['values']); | |
$issueCounts[$repoName] += $numResultsOnThisPage; | |
$page++; | |
} while (isset($resultsForPage['next'])); | |
$issuesAcrossAllRepos[$repoName] = $issuesForThisRepo; | |
} | |
$this->info('Number of issues per repo: ' . json_encode($issueCounts)); | |
return $issuesAcrossAllRepos; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment