Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/github_helper.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-10-29 16:20:00 +0300
committerMorris Jobke <hey@morrisjobke.de>2018-10-29 16:20:00 +0300
commite3fccc9f1b0df12c445ede6c0e10ce1245c007cc (patch)
tree01ab78dae1920a791c544a9cd37f0ed6a4d04090 /changelog
parentb112035eb8152ba8ca78ce8a7f10ffb979e72731 (diff)
Add changelog script for Android
Signed-off-by: Morris Jobke <hey@morrisjobke.de>
Diffstat (limited to 'changelog')
-rw-r--r--changelog/android.php308
1 files changed, 308 insertions, 0 deletions
diff --git a/changelog/android.php b/changelog/android.php
new file mode 100644
index 0000000..a0f6d03
--- /dev/null
+++ b/changelog/android.php
@@ -0,0 +1,308 @@
+<?php
+
+// This file is generated by Composer
+require_once __DIR__ . '/vendor/autoload.php';
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Helper\ProgressBar;
+# TODO
+#use Cache\Adapter\Redis\RedisCachePool;
+
+class GenerateChangelogCommand extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('generate:changelog')
+ ->setDescription('Generates the changelog.')
+ ->addArgument('base', InputArgument::REQUIRED, 'The base version.')
+ ->addArgument('head', InputArgument::REQUIRED, 'The head version.')
+ ->addOption(
+ 'format',
+ 'f',
+ InputOption::VALUE_REQUIRED,
+ 'What format should the output have? (markdown, forum, html)',
+ 'markdown'
+ );
+ ;
+ }
+
+ /**
+ * @throws Exception
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ // TODO iterate over all repos
+ $orgName = 'nextcloud';
+ $repoName = 'android';
+
+ $reposToIterate = [
+ "android",
+ /*"server",
+ "3rdparty",
+ "activity",
+ "apps",
+ "files_pdfviewer",
+ "files_texteditor",
+ "files_videoplayer",
+ "firstrunwizard",
+ "gallery",
+ "logreader",
+ "nextcloud_announcements",
+ "notifications",
+ "password_policy",
+ "serverinfo",
+ "survey_client",*/
+ ];
+
+
+ if (!file_exists(__DIR__ . '/../credentials.json')) {
+ throw new Exception('Credentials file is missing - please provide your credentials in credentials.json in the root folder.');
+ }
+
+ $credentialsData = json_decode(file_get_contents(__DIR__ . '/../credentials.json'), true);
+ if (!is_array($credentialsData) || !isset($credentialsData['apikey'])) {
+ throw new Exception('Credentials file can not be read or does not provide "apikey".');
+ }
+
+ $format = $input->getOption('format');
+ if (!in_array($format, ['markdown', 'forum', 'html'])) {
+ throw new \Symfony\Component\Console\Exception\InvalidOptionException(
+ "The provided format is invalid (should be one of markdown, forum, html but was '$format')"
+ );
+ }
+ $base = $input->getArgument('base');
+ $head = $input->getArgument('head');
+
+ $output->writeln("base: $base");
+ $output->writeln("head: $head");
+
+ $milestoneToCheck = null;
+ if (substr($base, 0, 7) === 'stable-') {
+ $version = explode('.', substr($base, 7));
+ if (count($version) !== 3) {
+ $output->writeln('<error>Detected version does not have exactly 3 numbers separated by a dot.</error>');
+ } else {
+ if (strpos($version[2], 'RC') !== false || strpos($version[2], 'beta') !== false) {
+ $version[2] = (string)((int)$version[2]); // this basically removes the beta/RC part
+ $milestoneToCheck = join('.', $version);
+
+ if (strpos($milestoneToCheck, '.0.0') !== false) {
+ $milestoneToCheck = str_replace('.0.0', '', $milestoneToCheck);
+ }
+ } else {
+ $version[2] = (string)((int)$version[2] + 1);
+ $milestoneToCheck = join('.', $version);
+ }
+ $output->writeln("Checking milestone $milestoneToCheck for pending PRs ...");
+ }
+ } else {
+ $output->writeln('<error>No version detected - the output will not contain any pending PRs. Use a git tag starting with "v" like "v13.0.5".</error>');
+ }
+
+ $prTitles = ['closed' => [], 'pending' => []];
+
+ # TODO
+ #$client = new \Redis();
+ #$client->connect('127.0.0.1', 6379);
+ // Create a PSR6 cache pool
+ #$pool = new RedisCachePool($client);
+
+ $client = new \Github\Client();
+ # TODO
+ #$client->addCache($pool);
+ $client->authenticate($credentialsData['apikey'], Github\Client::AUTH_URL_TOKEN);
+
+ $factor = 2;
+ if ($milestoneToCheck !== null) {
+ $factor = 3;
+ }
+
+ $progressBar = new ProgressBar($output, count($reposToIterate) * $factor);
+ $progressBar->setFormat(
+ implode(
+ "\n",
+ [
+ ' %message%',
+ ' %current%/%max% [%bar%] %percent:3s%%',
+ ' Remaining: %remaining:6s%',
+ ]
+ )
+ );
+ $progressBar->setMessage('Starting ...');
+ $progressBar->start();
+
+ foreach ($reposToIterate as $repoName) {
+
+ $pullRequests = [];
+ /** @var \Github\Api\Repo $repo */
+ $repo = $client->api('repo');
+ try {
+ $progressBar->setMessage("Fetching git history for $repoName...");
+ $diff = $repo->commits()->compare($orgName, $repoName, $base, $head);
+ } catch (\Github\Exception\RuntimeException $e) {
+ if ($e->getMessage() === 'Not Found') {
+ $output->writeln('<error>Could not find base or head reference.</error>');
+ return;
+ }
+ throw $e;
+ }
+
+ foreach ($diff['commits'] as $commit) {
+ $fullMessage = $commit['commit']['message'];
+ list($firstLine,) = explode("\n", $fullMessage, 2);
+ if (substr($firstLine, 0, 20) === 'Merge pull request #') {
+ $firstLine = substr($firstLine, 20);
+ list($number,) = explode(" ", $firstLine, 2);
+ $pullRequests[] = $number;
+ }
+ }
+ $progressBar->advance();
+
+ if ($milestoneToCheck !== null) {
+ $progressBar->setMessage("Fetching pending PRs for $repoName $milestoneToCheck ...");
+
+ $query = "query{
+ repository(owner: \"$orgName\", name: \"$repoName\") {
+ milestones(first: 20, states: [OPEN]) {
+ nodes {
+ title
+ pullRequests(states: [OPEN], first: 20) {
+ nodes {
+ number
+ }
+ }
+ }
+ }
+ }
+}";
+
+ $response = $client->api('graphql')->execute($query);
+ foreach ($response['data']['repository']['milestones']['nodes'] as $milestone) {
+ if (strpos($milestone['title'], $milestoneToCheck) !== false) {
+ foreach ($milestone['pullRequests']['nodes'] as $pr) {
+ $pullRequests[] = $pr['number'];
+ }
+ }
+ }
+ $progressBar->advance();
+ }
+
+ $query = <<<'QUERY'
+query {
+QUERY;
+ $query .= ' repository(owner: "' . $orgName . '", name: "' . $repoName . '") {';
+
+ foreach ($pullRequests as $pullRequest) {
+ $query .= "pr$pullRequest: pullRequest(number: $pullRequest) { number, title, state },";
+ }
+
+ $query .= <<<'QUERY'
+ }
+}
+QUERY;
+
+ $progressBar->setMessage("Fetching PR titles for $repoName ...");
+ $response = $client->api('graphql')->execute($query);
+
+ if (!isset($response['data']['repository'])) {
+ $progressBar->advance();
+ continue;
+ }
+ foreach ($response['data']['repository'] as $pr) {
+ $title = $pr['title'];
+ $title = preg_replace('!^(backport\W+#\d+:?)?\W*!i', '', $title);
+ $title = trim($title);
+ $title = strtoupper(substr($title, 0, 1)) . substr($title, 1);
+ $id = '#' . $pr['number'];
+ if ($repoName !== 'server') {
+ $id = $repoName . $id;
+ }
+ $data = [
+ 'repoName' => $repoName,
+ 'number' => $pr['number'],
+ 'title' => $title,
+ ];
+ if ($pr['state'] === 'MERGED') {
+ $prTitles['closed'][$id] = $data;
+ } else {
+ $prTitles['pending'][$id] = $data;
+ }
+ }
+ $progressBar->advance();
+ }
+ $progressBar->finish();
+
+ $output->writeln('');
+
+ ksort($prTitles['closed']);
+ ksort($prTitles['pending']);
+
+ switch($format) {
+ case 'html':
+ foreach($prTitles['closed'] as $id => $data) {
+ $repoName = $data['repoName'];
+ $number = $data['number'];
+ $title = $data['title'];
+ $output->writeln("<li><a href=\"https://github.com/$orgName/$repoName/pull/$number\">$title ($repoName#$number)</a></li>");
+ }
+ $count = count($prTitles['pending']);
+ if ($count > 0) {
+ $output->writeln("<error>$count pending PRs not printed - maybe the release is not ready yet</error>");
+ }
+ break;
+ case 'forum':
+ foreach($prTitles['closed'] as $id => $data) {
+ $repoName = $data['repoName'];
+ $number = $data['number'];
+ $title = $data['title'];
+ $output->writeln("* [$title ($repoName#$number)](https://github.com/$orgName/$repoName/pull/$number)");
+ }
+ $count = count($prTitles['pending']);
+ if ($count > 0) {
+ $output->writeln("<error>$count pending PRs not printed - maybe the release is not ready yet</error>");
+ }
+ break;
+ case 'markdown':
+ default:
+ foreach($prTitles['closed'] as $id => $data) {
+ $repoName = $data['repoName'];
+ $number = $data['number'];
+ $title = $data['title'];
+ if ($repoName === 'server') {
+ $output->writeln("* #$number $title");
+ } else {
+ $output->writeln("* [$repoName#$number](https://github.com/$orgName/$repoName/pull/$number) $title");
+ }
+ }
+ if (count($prTitles['pending'])) {
+ $output->writeln("\n\nPending PRs:\n");
+ }
+ foreach($prTitles['pending'] as $id => $data) {
+ $repoName = $data['repoName'];
+ $number = $data['number'];
+ $title = $data['title'];
+ if ($repoName === 'server') {
+ $output->writeln("* [ ] #$number $title");
+ } else {
+ $output->writeln("* [ ] [$repoName#$number](https://github.com/$orgName/$repoName/pull/$number) $title");
+ }
+ }
+ break;
+ }
+
+ // Stop using cache
+ # TODO
+ #$client->removeCache();
+ }
+}
+
+$application = new Application();
+
+$application->add(new GenerateChangelogCommand());
+$application->run();