Skip to content

Commit

Permalink
add experimental webhook feature, simple bitbucket interface, event for
Browse files Browse the repository at this point in the history
  • Loading branch information
ramunasd committed Aug 29, 2018
1 parent 3e71b64 commit b07d85e
Show file tree
Hide file tree
Showing 10 changed files with 379 additions and 40 deletions.
8 changes: 7 additions & 1 deletion app/MicroKernel.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<?php

use RDV\SymfonyContainerMocks\DependencyInjection\TestKernelTrait;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\RouteCollectionBuilder;
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;

class MicroKernel extends Kernel
{
use MicroKernelTrait;
use TestKernelTrait;

/**
* {@inheritdoc}
Expand Down Expand Up @@ -76,6 +78,10 @@ protected function configureRoutes(RouteCollectionBuilder $routes)
$routes
->add('/admin/satis/buildRun', $controllerBase . 'SatisController::buildRunAction', 'satis_build_run')
->setMethods(['GET']);
// webhooks
$routes
->add('/webhook/bitbucket', $controllerBase . 'WebhookController::bitbucketAction', 'webhook_bitbucket')
->setMethods(['GET', 'POST']);
}

// optional, to use the standard Symfony cache directory
Expand Down
32 changes: 32 additions & 0 deletions src/Playbloom/Satisfy/Controller/WebhookController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Playbloom\Satisfy\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;

class WebhookController extends Controller
{
/**
* @param Request $request
* @return Response
* @throws BadRequestHttpException
* @throws ServiceUnavailableHttpException
*/
public function bitbucketAction(Request $request): Response
{
$webhook = $this->container->get('satisfy.webhook.bitbucket');
try {
$status = $webhook->handle($request);
} catch (\InvalidArgumentException $exception) {
throw new BadRequestHttpException();
} catch (\Throwable $exception) {
throw new ServiceUnavailableHttpException();
}

return new Response($status);
}
}
43 changes: 43 additions & 0 deletions src/Playbloom/Satisfy/Event/BuildEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Playbloom\Satisfy\Event;

use Playbloom\Satisfy\Model\RepositoryInterface;
use Symfony\Component\EventDispatcher\Event;

class BuildEvent extends Event
{
const EVENT_NAME = 'satis_build';

/** @var RepositoryInterface|null */
private $repository;

/** @var int|null */
private $status;

public function __construct(RepositoryInterface $repository = null)
{
$this->repository = $repository;
}

/**
* @return RepositoryInterface|null
*/
public function getRepository()
{
return $this->repository;
}

/**
* @return int|null
*/
public function getStatus()
{
return $this->status;
}

public function setStatus(int $status)
{
$this->status = $status;
}
}
9 changes: 5 additions & 4 deletions src/Playbloom/Satisfy/Model/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ class Repository implements RepositoryInterface
private $url;

/**
* Initialize with default opinionated values
* @param string $url
* @param string $type
*/
public function __construct()
public function __construct(string $url = '', string $type = 'git')
{
$this->type = 'git';
$this->url = '';
$this->url = $url;
$this->type = $type;
}

/**
Expand Down
53 changes: 53 additions & 0 deletions src/Playbloom/Satisfy/Process/ProcessFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Playbloom\Satisfy\Process;

use Symfony\Component\Process\Process;

class ProcessFactory
{
/** @var string */
protected $rootPath;

/** @var string */
protected $homePath;

public function __construct(string $rootPath, string $homePath)
{
$this->rootPath = $rootPath;
$this->homePath = $homePath;
}

public function getRootPath(): string
{
return $this->rootPath;
}

public function create(string $command, int $timeout = null): Process
{
return new Process($command, $this->rootPath, $this->getEnv(), null, $timeout);
}

protected function getEnv(): array
{
$env = [];

foreach ($_SERVER as $k => $v) {
if (is_string($v) && false !== $v = getenv($k)) {
$env[$k] = $v;
}
}

foreach ($_ENV as $k => $v) {
if (is_string($v)) {
$env[$k] = $v;
}
}

if (empty($env['HOME'])) {
$env['HOME'] = $this->homePath;
}

return $env;
}
}
21 changes: 18 additions & 3 deletions src/Playbloom/Satisfy/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,24 @@ services:
arguments:
- "@satisfy.manager"

satisfy.process.factory:
class: Playbloom\Satisfy\Process\ProcessFactory
arguments:
- "%kernel.project_dir%"
- "%composer.home%"

satisfy.runner.satis_build:
class: Playbloom\Satisfy\Runner\SatisBuildRunner
arguments:
- '%kernel.project_dir%'
- '%satis_filename%'
- '%composer.home%'
- "%satis_filename%"
calls:
- [setProcessFactory, ["@satisfy.process.factory"]]
tags:
- { name: kernel.event_listener, event: "satis_build", method: onBuild }

### Webhook handlers
satisfy.webhook.bitbucket:
class: Playbloom\Satisfy\Webhook\BitbucketWebhook
arguments:
- "@satisfy.manager"
- "@event_dispatcher"
64 changes: 32 additions & 32 deletions src/Playbloom/Satisfy/Runner/SatisBuildRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,39 @@

namespace Playbloom\Satisfy\Runner;

use Symfony\Component\Process\Process;
use Playbloom\Satisfy\Event\BuildEvent;
use Playbloom\Satisfy\Process\ProcessFactory;
use Symfony\Component\Process\Exception\RuntimeException;

class SatisBuildRunner
{
/** @var string */
protected $rootPath;

/** @var string */
protected $satisFilename;

/** @var string */
protected $homePath;
/** @var ProcessFactory */
protected $processFactory;

/** @var int */
protected $timeout = 600;

public function __construct(string $rootPath, string $satisFilename, string $homePath)
public function __construct(string $satisFilename)
{
$this->rootPath = $rootPath;
$this->satisFilename = $satisFilename;
$this->homePath = $homePath;
}

public function setProcessFactory(ProcessFactory $processFactory)
{
$this->processFactory = $processFactory;

return $this;
}

/**
* @return \Generator|string[]
*/
public function run(): \Generator
{
$process = new Process($this->getCommandLine(), $this->rootPath, $this->getEnv(), null, $this->timeout);
$process = $this->processFactory->create($this->getCommandLine());
$process->start();

yield $process->getCommandLine();
Expand All @@ -46,34 +50,30 @@ public function run(): \Generator
yield $process->getExitCodeText();
}

protected function getCommandLine(): string
public function onBuild(BuildEvent $event)
{
$line = $this->rootPath . '/bin/satis build';
$line .= ' --skip-errors --no-ansi --no-interaction --verbose';
$repository = $event->getRepository();
$command = $this->getCommandLine($repository ? $repository->getUrl() : null);
$process = $this->processFactory->create($command, $this->timeout);
$process->disableOutput();

try {
$status = $process->run();
} catch (RuntimeException $exception) {
$status = 1;
}

return $line;
$event->setStatus($status);
}

protected function getEnv(): array
protected function getCommandLine(string $repositoryUrl = null): string
{
$env = [];

foreach ($_SERVER as $k => $v) {
if (is_string($v) && false !== $v = getenv($k)) {
$env[$k] = $v;
}
}

foreach ($_ENV as $k => $v) {
if (is_string($v)) {
$env[$k] = $v;
}
}

if (empty($env['HOME'])) {
$env['HOME'] = $this->homePath;
$line = $this->processFactory->getRootPath() . '/bin/satis build';
$line .= ' --skip-errors --no-ansi --no-interaction --verbose';
if (!empty($repositoryUrl)) {
$line .= sprintf(' --repository-url="%s"', $repositoryUrl);
}

return $env;
return $line;
}
}
16 changes: 16 additions & 0 deletions src/Playbloom/Satisfy/Service/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PhpOption\None;
use Playbloom\Satisfy\Exception\MissingConfigException;
use Playbloom\Satisfy\Model\Configuration;
use Playbloom\Satisfy\Model\Repository;
use Playbloom\Satisfy\Model\RepositoryInterface;
use Playbloom\Satisfy\Persister\PersisterInterface;
use Symfony\Component\Filesystem\Exception\IOException;
Expand Down Expand Up @@ -66,6 +67,21 @@ public function findOneRepository($id)
return $repository->get();
}

/**
* @param string $pattern
* @return RepositoryInterface|null
*/
public function findByUrl(string $pattern)
{
foreach ($this->getRepositories() as $repository) {
if (preg_match($pattern, $repository->getUrl())) {
return $repository;
}
}

return null;
}

/**
* Add a new repository
*
Expand Down
Loading

0 comments on commit b07d85e

Please sign in to comment.