diff --git a/src/Commands/PublishReleaseCommand.php b/src/Commands/PublishReleaseCommand.php new file mode 100644 index 0000000..228ad21 --- /dev/null +++ b/src/Commands/PublishReleaseCommand.php @@ -0,0 +1,119 @@ +setName('release') + ->setDescription('Fake the release-published event for $tag.') + ->addArgument( + 'repository', + InputArgument::REQUIRED, + 'Full repository name, including the owner. Example: styxit/deployments' + ) + ->addArgument( + 'tag', + InputArgument::REQUIRED, + 'The tag to fake. Example: v1.0.2' + ); + } + + /** + * Execute the command. + * + * @param InputInterface $input + * @param OutputInterface $output + * + * @return int The exit code. + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->writeLn(''); + + list($repositoryOwner, $repositoryName) = explode('/', $input->getArgument('repository')); + + $output->writeLn('About to spoof a "release published" event with the following settings:'); + $output->writeLn(''); + $output->writeLn(sprintf('Repository: %s/%s', $repositoryOwner, $repositoryName)); + $output->writeln( + sprintf( + 'Release tag: %s.', + $input->getArgument('tag') + ) + ); + $output->writeLn(''); + + // Ask confirmation. + if (!$this->confirm($input, $output, 'Is this correct?')) { + $output->writeLn('User did not confirm. Quit.'); + + return; + } + + // Construct payload from template. + $payload = (new Parser('release-published'))->parse( + [ + 'repoName' => $repositoryName, + 'repoOwner' => $repositoryOwner, + 'repoFullName' => $repositoryOwner.'/'.$repositoryName, + 'tagName' => $input->getArgument('tag'), + ] + ); + + // Get the payload signature. + $signature = (new Signer())->sign($payload); + + $output->writeLn('Spoofing the event...'); + + // Construct and execute the request. + $client = new Client(); + $client->post( + $_ENV['DESTINATION_URL'], + [ + 'body' => $payload, + 'headers' => [ + 'Content-Type' => 'application/json', + 'X-Hub-Signature' => 'sha1='.$signature, + 'X-GitHub-Event' => 'release', + ] + ] + ); + + $output->writeLn('Done.'); + } + + /** + * Ask a question the user must answer with 'y' or 'n'. + * + * @param InputInterface $input + * @param OutputInterface $output + * @param string $question The question to ask. + * + * @return bool True when the user entered 'y', False otherwise. + */ + private function confirm(InputInterface $input, OutputInterface $output, $question = 'Ok?') + { + $helper = $this->getHelper('question'); + $confirmQuestion = new ConfirmationQuestion($question.' [y/n]: ', false); + + if (!$helper->ask($input, $output, $confirmQuestion)) { + return false; + } + + return true; + } +} diff --git a/templates/release-published.json b/templates/release-published.json new file mode 100644 index 0000000..f8ea6ef --- /dev/null +++ b/templates/release-published.json @@ -0,0 +1,13 @@ +{ + "action": "published", + "repository": { + "name": "%s", + "owner": { + "login": "%s" + }, + "ssh_url": "http://github.com/%s" + }, + "release": { + "tag_name": "%s" + } +}