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();
+ }
+}