diff --git a/readme.md b/readme.md index 4f9cd5f..d3b2b63 100644 --- a/readme.md +++ b/readme.md @@ -40,7 +40,8 @@ cow release:publish 3.1.14-rc1 -vvv ## Release -`cow release ` will perform all release tasks. is mandatory and must be the exact tag name to release. +`cow release ` will perform the first part of the release tasks. + is mandatory and must be the exact tag name to release. This command has these options: @@ -53,8 +54,6 @@ it will install to the path specified by `./release-` in the current di If omitted, no branching is performed. `--branch-auto` can be used to just default to the major.minor.patch version of the release. It's advisable to specify this, but not always necessary, when doing pre-releases. -## Release sub-commands - `release` actually has several sub-commands which can be run independently. These are as below: * `release:create` creates the project folder @@ -80,8 +79,6 @@ This command has these options: * `--aws-profile ` to specify the AWS profile name for uploading releases to s3. Check with damian@silverstripe.com if you don't have an AWS key setup. -## Publish sub-commands - The release process, as with the initial `cow release` command, will actually be composed of several sub-commands, each of which could be run separately. @@ -90,6 +87,9 @@ each of which could be run separately. * `release:archive` Generate tar.gz and zip archives of this release * `release:upload` Upload archived projects to silverstripe.org +After the push step, `release:publish` will automatically wait for this version to be available in packagist.org +before continuing. + ## Module-level commands Outside of doing core releases, you can use this for specific modules diff --git a/src/Commands/Release/Publish.php b/src/Commands/Release/Publish.php index bada4b8..82e5795 100644 --- a/src/Commands/Release/Publish.php +++ b/src/Commands/Release/Publish.php @@ -6,6 +6,7 @@ use SilverStripe\Cow\Steps\Release\PushRelease; use SilverStripe\Cow\Steps\Release\TagModules; use SilverStripe\Cow\Steps\Release\UploadArchive; +use SilverStripe\Cow\Steps\Release\Wait; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -42,6 +43,10 @@ protected function fire() { $push = new PushRelease($this, $directory, $modules); $push->run($this->input, $this->output); + // Once pushed, wait until installable + $wait = new Wait($this, $version); + $wait->run($this->input, $this->output); + // Create packages $package = new BuildArchive($this, $version, $directory); $package->run($this->input, $this->output); diff --git a/src/Steps/Release/Wait.php b/src/Steps/Release/Wait.php new file mode 100644 index 0000000..ad0bfcd --- /dev/null +++ b/src/Steps/Release/Wait.php @@ -0,0 +1,108 @@ +version = $version; + } + + /** + * Create a new project + * + * @param InputInterface $input + * @param OutputInterface $output + */ + public function run(InputInterface $input, OutputInterface $output) { + $version = $this->version->getValue(); + $this->log($output, "Waiting for version {$version} to be available via packagist"); + $this->waitLoop($output); + $this->log($output, "Version {$version} is now available"); + } + + protected function waitLoop(OutputInterface $output) { + $start = time(); + $version = $this->version->getValue(); + while($start + $this->timeout >= time()) { + $versions = $this->getAvailableVersions($output); + if(in_array($version, $versions)) { + return; + } + // Wait + $this->log($output, "Version {$version} not available; checking again in 20 seconds"); + + // Progress bar for 20 seconds + $progress = new ProgressBar($output, 20); + $progress->start(); + for($i = 0; $i < 20; $i++) { + $progress->advance(); + sleep(1); + } + $progress->finish(); + $output->writeln(''); + } + + // Timeout + throw new Exception( + "Waiting for version {$version} to be available timed out after " . $this->timeout . " seconds" + ); + } + + /** + * Determine installable versions composer knows about and can install + * + * @return array + */ + protected function getAvailableVersions(OutputInterface $output) { + $error = "Could not parse available versions from command \"composer show {$this->package}\""; + $output = $this->runCommand($output, array("composer", "show", $this->package), $error); + + // Parse output + if($output && preg_match('/^versions\s*:\s*(?(\S.+\S))\s*$/m', $output, $matches)) { + return preg_split('/\s*,\s*/', $matches['versions']); + } + + throw new Exception($error); + } + + public function getStepName() { + return 'wait'; + } + +}