diff --git a/src/ApplicationFactory.php b/src/ApplicationFactory.php index 19c9afa..ba9f8b2 100644 --- a/src/ApplicationFactory.php +++ b/src/ApplicationFactory.php @@ -8,6 +8,7 @@ use Continuous\Cli\Command\Company\CompanyListCommand; use Continuous\Cli\Command\ConfigureCommand; use Continuous\Cli\Command\Pipeline\PipelineExportCommand; +use Continuous\Cli\Command\Package\PackageDownloadCommand; use Continuous\Cli\Command\Project\ProjectListCommand; use Continuous\Cli\Command\Repository\RepositoryListCommand; use Symfony\Component\Console\Application; @@ -36,6 +37,7 @@ public function create() $application->add(new BuildStartCommand()); $application->add(new BuildStopCommand()); $application->add(new PipelineExportCommand()); + $application->add(new PackageDownloadCommand()); return $application; } diff --git a/src/Command/Build/BuildListCommand.php b/src/Command/Build/BuildListCommand.php index 6258975..ef592ae 100644 --- a/src/Command/Build/BuildListCommand.php +++ b/src/Command/Build/BuildListCommand.php @@ -35,7 +35,7 @@ protected function configure() 's', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'the build status', - Build::STATE + Build::STATES ) ->addOption( 'noPr', diff --git a/src/Command/Package/PackageDownloadCommand.php b/src/Command/Package/PackageDownloadCommand.php new file mode 100644 index 0000000..15658f0 --- /dev/null +++ b/src/Command/Package/PackageDownloadCommand.php @@ -0,0 +1,134 @@ +setName('package:download') + ->setDescription('Download package of continuousphp build.') + ->setHelp('This command download package for latest build of pipeline the one you specify by build ID.') + ->addArgument('provider', InputArgument::REQUIRED, 'The repository provider') + ->addArgument('repository', InputArgument::REQUIRED, 'The repository name') + ->addArgument('destination', InputArgument::OPTIONAL, 'The destination path of package file, by default current workdir') + ; + + $this + ->addOption( + 'ref', + 'r', + InputOption::VALUE_OPTIONAL, + 'The git reference' + ) + ->addOption( + 'id', + 'i', + InputOption::VALUE_OPTIONAL, + 'The build ID' + ) + ->addOption( + 'type', + 't', + InputOption::VALUE_OPTIONAL, + 'The package type (deploy|test)', + 'deploy' + ) + ->addOption( + 'pr', + 'p', + InputOption::VALUE_OPTIONAL, + 'The Pull Request ID' + ); + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int|null|void + * @throws \Continuous\Sdk\Exception + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + parent::execute($input, $output); + + $packageType = $input->getOption('type'); + $buildId = $input->getOption('id'); + $destination = getcwd() . '/' . $input->getArgument('destination'); + + if (false === file_exists($destination)) { + return $output->writeln( + "ERROR : directory $destination not exist" + ); + } + + if (!$buildId && $latestBuild = $this->findLastBuildId($input, $output)) { + $buildId = $latestBuild->get('buildId'); + } + + if (false === in_array($packageType, static::PACKAGE_TYPES)) { + return $output->writeln( + "ERROR : package type option must be deploy or test only" + ); + } + + if (!$buildId) { + return $output->writeln( + "ERROR : no build ID has been found" + ); + } + + $package = $this->continuousClient->downloadPackage([ + 'provider' => static::mapProviderToSdk($input->getArgument('provider')), + 'repository' => $input->getArgument('repository'), + 'buildId' => $buildId, + 'packageType' => $packageType, + 'destination' => getcwd() . '/' . $input->getArgument('destination') + ]); + + $output->writeln('Package downloaded at ' . $package['path']); + } + + /** + * Find the latest build of repository + * @param InputInterface $input + * @param OutputInterface $output + * @return mixed|null + */ + private function findLastBuildId(InputInterface $input, OutputInterface $output): ?Build + { + $pr = $input->getOption('pr'); + $filters = [ + 'provider' => static::mapProviderToSdk($input->getArgument('provider')), + 'repository' => $input->getArgument('repository'), + 'result' => ['success', 'warning'], + 'state' => ['complete'], + 'exclude_pull_requests' => !$pr ? 1 : 0, + 'page_size' => 1, + ]; + + if ($input->hasOption('ref')) { + $filters['pipeline_id'] = $input->getOption('ref'); + } + + if ($pr) { + $filters['pull_request_id'] = (int)$pr; + } + + /** @var Collection $builds $builds */ + $builds = $this->continuousClient->getBuilds($filters); + + return 0 === $builds->count() ? null : $builds->getIterator()->current(); + } +}