Merge remote-tracking branch 'origin/master' into feature/pluginfactoryconfig
Conflicts: PHPCI/Builder.php PHPCI/Plugin/Util/Factory.php
This commit is contained in:
commit
060a786303
|
@ -10,6 +10,7 @@
|
|||
namespace PHPCI;
|
||||
|
||||
use b8;
|
||||
use b8\Http\Response;
|
||||
use b8\Http\Response\RedirectResponse;
|
||||
use b8\View;
|
||||
|
||||
|
@ -19,52 +20,37 @@ use b8\View;
|
|||
*/
|
||||
class Application extends b8\Application
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
$request =& $this->request;
|
||||
$route = '/:controller/:action';
|
||||
$opts = array('controller' => 'Home', 'action' => 'index');
|
||||
|
||||
$this->router->clearRoutes();
|
||||
$this->router->register($route, $opts, function (&$route, Response &$response) use (&$request) {
|
||||
$skipValidation = in_array($route['controller'], array('session', 'webhook', 'build-status'));
|
||||
|
||||
if (!$skipValidation && !$this->validateSession()) {
|
||||
if ($request->isAjax()) {
|
||||
$response->setResponseCode(401);
|
||||
$response->setContent('');
|
||||
} else {
|
||||
$response = new RedirectResponse($response);
|
||||
$response->setHeader('Location', PHPCI_URL.'session/login');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Handle an incoming web request.
|
||||
*/
|
||||
public function handleRequest()
|
||||
{
|
||||
try {
|
||||
$this->initRequest();
|
||||
|
||||
// Validate the user's session unless it is a login/logout action or a web hook:
|
||||
$sessionAction = ($this->controllerName == 'Session' && in_array($this->action, array('login', 'logout')));
|
||||
$externalAction = in_array($this->controllerName, array('Bitbucket', 'Github', 'Gitlab', 'BuildStatus', 'Git'));
|
||||
$skipValidation = ($externalAction || $sessionAction);
|
||||
|
||||
if ($skipValidation || $this->validateSession()) {
|
||||
parent::handleRequest();
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
$content = '<h1>There was a problem with this request</h1>
|
||||
<p>Please paste the details below into a
|
||||
<a href="https://github.com/Block8/PHPCI/issues/new">new bug report</a>
|
||||
so that we can investigate and fix it.</p>';
|
||||
|
||||
ob_start();
|
||||
var_dump(array(
|
||||
'message' => $ex->getMessage(),
|
||||
'file' => $ex->getFile(),
|
||||
'line' => $ex->getLine(),
|
||||
'trace' => $ex->getTraceAsString()
|
||||
));
|
||||
var_dump(array(
|
||||
'PATH_INFO' => $_SERVER['PATH_INFO'],
|
||||
'REDIRECT_PATH_INFO' => $_SERVER['REDIRECT_PATH_INFO'],
|
||||
'REQUEST_URI' => $_SERVER['REQUEST_URI'],
|
||||
'PHP_SELF' => $_SERVER['PHP_SELF'],
|
||||
'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
|
||||
'DOCUMENT_ROOT' => $_SERVER['DOCUMENT_ROOT'],
|
||||
'SCRIPT_FILENAME' => $_SERVER['SCRIPT_FILENAME'],
|
||||
'SERVER_SOFTWARE' => $_SERVER['SERVER_SOFTWARE'],
|
||||
));
|
||||
$content .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$this->response->setContent($content);
|
||||
$this->response->disableLayout();
|
||||
}
|
||||
|
||||
$this->response = parent::handleRequest();
|
||||
|
||||
if (View::exists('layout') && $this->response->hasLayout()) {
|
||||
$view = new View('layout');
|
||||
|
@ -91,14 +77,6 @@ class Application extends b8\Application
|
|||
unset($_SESSION['user_id']);
|
||||
}
|
||||
|
||||
if ($this->request->isAjax()) {
|
||||
$this->response->setResponseCode(401);
|
||||
$this->response->setContent('');
|
||||
} else {
|
||||
$this->response = new RedirectResponse($this->response);
|
||||
$this->response->setHeader('Location', PHPCI_URL.'session/login');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,8 @@
|
|||
|
||||
namespace PHPCI;
|
||||
|
||||
use b8\Store\Factory;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Model\Build\LocalBuild;
|
||||
use PHPCI\Model\Build\GithubBuild;
|
||||
use PHPCI\Model\Build\BitbucketBuild;
|
||||
|
||||
/**
|
||||
* PHPCI Build Factory - Takes in a generic "Build" and returns a type-specific build model.
|
||||
|
@ -20,9 +18,21 @@ use PHPCI\Model\Build\BitbucketBuild;
|
|||
*/
|
||||
class BuildFactory
|
||||
{
|
||||
/**
|
||||
* @param $buildId
|
||||
* @return Build
|
||||
*/
|
||||
public static function getBuildById($buildId)
|
||||
{
|
||||
$build = Factory::getStore('Build')->getById($buildId);
|
||||
|
||||
return self::getBuild($build);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a generic build and returns a type-specific build model.
|
||||
* @return \PHPCI\Model\Build\LocalBuild|\PHPCI\Model\Build\GithubBuild|\PHPCI\Model\Build\BitbucketBuild
|
||||
* @param Build $base The build from which to get a more specific build type.
|
||||
* @return Build
|
||||
*/
|
||||
public static function getBuild(Build $base)
|
||||
{
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
namespace PHPCI;
|
||||
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* PHPCI Build Logger
|
||||
*/
|
||||
interface BuildLogger
|
||||
{
|
||||
/**
|
||||
* Add an entry to the build log.
|
||||
* @param string|string[] $message
|
||||
* @param string $level
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function log($message, $level = LogLevel::INFO, $context = array());
|
||||
|
||||
/**
|
||||
* Add a success-coloured message to the log.
|
||||
* @param string
|
||||
*/
|
||||
public function logSuccess($message);
|
||||
|
||||
/**
|
||||
* Add a failure-coloured message to the log.
|
||||
* @param string $message
|
||||
* @param \Exception $exception The exception that caused the error.
|
||||
*/
|
||||
public function logFailure($message, \Exception $exception = null);
|
||||
}
|
|
@ -9,21 +9,23 @@
|
|||
|
||||
namespace PHPCI;
|
||||
|
||||
use PHPCI\Helper\BuildInterpolator;
|
||||
use PHPCI\Helper\CommandExecutor;
|
||||
use PHPCI\Helper\MailerFactory;
|
||||
use PHPCI\Logging\BuildLogger;
|
||||
use PHPCI\Model\Build;
|
||||
use b8\Store;
|
||||
use b8\Config;
|
||||
use PHPCI\Plugin\Util\Factory;
|
||||
use b8\Store\Factory;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use PHPCI\Plugin\Util\Factory as PluginFactory;
|
||||
|
||||
/**
|
||||
* PHPCI Build Runner
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
*/
|
||||
class Builder implements LoggerAwareInterface, BuildLogger
|
||||
class Builder implements LoggerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
|
@ -76,12 +78,9 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
protected $lastOutput;
|
||||
|
||||
/**
|
||||
* An array of key => value pairs that will be used for
|
||||
* interpolation and environment variables
|
||||
* @var array
|
||||
* @see setInterpolationVars()
|
||||
* @var BuildInterpolator
|
||||
*/
|
||||
protected $interpolation_vars = array();
|
||||
protected $interpolator;
|
||||
|
||||
/**
|
||||
* @var \PHPCI\Store\BuildStore
|
||||
|
@ -103,24 +102,36 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
*/
|
||||
protected $commandExecutor;
|
||||
|
||||
/**
|
||||
* @var Logging\BuildLogger
|
||||
*/
|
||||
protected $buildLogger;
|
||||
|
||||
/**
|
||||
* Set up the builder.
|
||||
* @param \PHPCI\Model\Build $build
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(Build $build, $logger = null)
|
||||
public function __construct(Build $build, LoggerInterface $logger = null)
|
||||
{
|
||||
if ($logger) {
|
||||
$this->setLogger($logger);
|
||||
}
|
||||
$this->build = $build;
|
||||
$this->store = Store\Factory::getStore('Build');
|
||||
$this->store = Factory::getStore('Build');
|
||||
|
||||
$this->buildLogger = new BuildLogger($logger, $build);
|
||||
|
||||
$pluginFactory = $this->buildPluginFactory($build);
|
||||
$pluginFactory->addConfigFromFile(PHPCI_DIR . "/pluginconfig.php");
|
||||
$this->pluginExecutor = new Plugin\Util\Executor($pluginFactory, $this);
|
||||
|
||||
$this->commandExecutor = new CommandExecutor($this, PHPCI_DIR, $this->quiet, $this->verbose);
|
||||
$this->commandExecutor = new CommandExecutor(
|
||||
$this->buildLogger,
|
||||
PHPCI_DIR,
|
||||
$this->quiet,
|
||||
$this->verbose
|
||||
);
|
||||
|
||||
$this->interpolator = new BuildInterpolator();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -189,8 +200,7 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
// stages.
|
||||
if ($this->success) {
|
||||
$this->build->setStatus(Build::STATUS_SUCCESS);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->build->setStatus(Build::STATUS_FAILED);
|
||||
}
|
||||
|
||||
|
@ -199,15 +209,14 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
|
||||
if ($this->success) {
|
||||
$this->pluginExecutor->executePlugins($this->config, 'success');
|
||||
$this->logSuccess('BUILD SUCCESSFUL!');
|
||||
}
|
||||
else {
|
||||
$this->buildLogger->logSuccess('BUILD SUCCESSFUL!');
|
||||
} else {
|
||||
$this->pluginExecutor->executePlugins($this->config, 'failure');
|
||||
$this->logFailure("BUILD FAILURE");
|
||||
$this->buildLogger->logFailure("BUILD FAILURE");
|
||||
}
|
||||
|
||||
// Clean up:
|
||||
$this->log('Removing build.');
|
||||
$this->buildLogger->log('Removing build.');
|
||||
shell_exec(sprintf('rm -Rf "%s"', $this->buildPath));
|
||||
|
||||
// Update the build in the database, ping any external services, etc.
|
||||
|
@ -243,107 +252,14 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
}
|
||||
|
||||
/**
|
||||
* Add an entry to the build log.
|
||||
* @param string|string[] $message
|
||||
* @param string $level
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function log($message, $level = LogLevel::INFO, $context = array())
|
||||
{
|
||||
// Skip if no logger has been loaded.
|
||||
if (!$this->logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_array($message)) {
|
||||
$message = array($message);
|
||||
}
|
||||
|
||||
// The build is added to the context so the logger can use
|
||||
// details from it if required.
|
||||
$context['build'] = $this->build;
|
||||
|
||||
foreach ($message as $item) {
|
||||
$this->logger->log($level, $item, $context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a success-coloured message to the log.
|
||||
* @param string
|
||||
*/
|
||||
public function logSuccess($message)
|
||||
{
|
||||
$this->log("\033[0;32m" . $message . "\033[0m");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a failure-coloured message to the log.
|
||||
* @param string $message
|
||||
* @param \Exception $exception The exception that caused the error.
|
||||
*/
|
||||
public function logFailure($message, \Exception $exception = null)
|
||||
{
|
||||
$context = array();
|
||||
|
||||
// The psr3 log interface stipulates that exceptions should be passed
|
||||
// as the exception key in the context array.
|
||||
if ($exception) {
|
||||
$context['exception'] = $exception;
|
||||
}
|
||||
|
||||
$this->log(
|
||||
"\033[0;31m" . $message . "\033[0m",
|
||||
LogLevel::ERROR,
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace every occurance of the interpolation vars in the given string
|
||||
* Replace every occurrence of the interpolation vars in the given string
|
||||
* Example: "This is build %PHPCI_BUILD%" => "This is build 182"
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public function interpolate($input)
|
||||
{
|
||||
$keys = array_keys($this->interpolation_vars);
|
||||
$values = array_values($this->interpolation_vars);
|
||||
return str_replace($keys, $values, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the variables that will be used for interpolation. This must be run
|
||||
* from setupBuild() because prior to that, we don't know the buildPath
|
||||
*/
|
||||
protected function setInterpolationVars()
|
||||
{
|
||||
$this->interpolation_vars = array();
|
||||
$this->interpolation_vars['%PHPCI%'] = 1;
|
||||
$this->interpolation_vars['%COMMIT%'] = $this->build->getCommitId();
|
||||
$this->interpolation_vars['%PROJECT%'] = $this->build->getProjectId();
|
||||
$this->interpolation_vars['%BUILD%'] = $this->build->getId();
|
||||
$this->interpolation_vars['%PROJECT_TITLE%'] = $this->getBuildProjectTitle(
|
||||
);
|
||||
$this->interpolation_vars['%BUILD_PATH%'] = $this->buildPath;
|
||||
$this->interpolation_vars['%BUILD_URI%'] = PHPCI_URL . "build/view/" . $this->build->getId(
|
||||
);
|
||||
$this->interpolation_vars['%PHPCI_COMMIT%'] = $this->interpolation_vars['%COMMIT%'];
|
||||
$this->interpolation_vars['%PHPCI_PROJECT%'] = $this->interpolation_vars['%PROJECT%'];
|
||||
$this->interpolation_vars['%PHPCI_BUILD%'] = $this->interpolation_vars['%BUILD%'];
|
||||
$this->interpolation_vars['%PHPCI_PROJECT_TITLE%'] = $this->interpolation_vars['%PROJECT_TITLE%'];
|
||||
$this->interpolation_vars['%PHPCI_BUILD_PATH%'] = $this->interpolation_vars['%BUILD_PATH%'];
|
||||
$this->interpolation_vars['%PHPCI_BUILD_URI%'] = $this->interpolation_vars['%BUILD_URI%'];
|
||||
|
||||
putenv('PHPCI=1');
|
||||
putenv('PHPCI_COMMIT=' . $this->interpolation_vars['%COMMIT%']);
|
||||
putenv('PHPCI_PROJECT=' . $this->interpolation_vars['%PROJECT%']);
|
||||
putenv('PHPCI_BUILD=' . $this->interpolation_vars['%BUILD%']);
|
||||
putenv(
|
||||
'PHPCI_PROJECT_TITLE=' . $this->interpolation_vars['%PROJECT_TITLE%']
|
||||
);
|
||||
putenv('PHPCI_BUILD_PATH=' . $this->interpolation_vars['%BUILD_PATH%']);
|
||||
putenv('PHPCI_BUILD_URI=' . $this->interpolation_vars['%BUILD_URI%']);
|
||||
return $this->interpolator->interpolate($input);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -351,12 +267,17 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
*/
|
||||
protected function setupBuild()
|
||||
{
|
||||
$buildId = 'project' . $this->build->getProject()->getId(
|
||||
) . '-build' . $this->build->getId();
|
||||
$this->ciDir = dirname(__FILE__) . '/../';
|
||||
$buildId = 'project' . $this->build->getProject()->getId()
|
||||
. '-build' . $this->build->getId();
|
||||
$this->ciDir = dirname(dirname(__FILE__) . '/../') . '/';
|
||||
$this->buildPath = $this->ciDir . 'build/' . $buildId . '/';
|
||||
$this->build->currentBuildPath = $this->buildPath;
|
||||
|
||||
$this->setInterpolationVars();
|
||||
$this->interpolator->setupInterpolationVars(
|
||||
$this->build,
|
||||
$this->buildPath,
|
||||
PHPCI_URL
|
||||
);
|
||||
|
||||
// Create a working copy of the project:
|
||||
if (!$this->build->createWorkingCopy($this, $this->buildPath)) {
|
||||
|
@ -373,7 +294,7 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
$this->ignore = $this->config['build_settings']['ignore'];
|
||||
}
|
||||
|
||||
$this->logSuccess('Working copy created: ' . $this->buildPath);
|
||||
$this->buildLogger->logSuccess('Working copy created: ' . $this->buildPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -385,32 +306,45 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->buildLogger->setLogger($logger);
|
||||
}
|
||||
|
||||
public function log($message, $level = LogLevel::INFO, $context = array())
|
||||
{
|
||||
$this->buildLogger->log($message, $level, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a success-coloured message to the log.
|
||||
* @param string
|
||||
*/
|
||||
public function logSuccess($message)
|
||||
{
|
||||
$this->buildLogger->logSuccess($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the logger attached to this builder.
|
||||
*
|
||||
* @return LoggerInterface
|
||||
* Add a failure-coloured message to the log.
|
||||
* @param string $message
|
||||
* @param \Exception $exception The exception that caused the error.
|
||||
*/
|
||||
public function getLogger()
|
||||
public function logFailure($message, \Exception $exception = null)
|
||||
{
|
||||
return $this->logger;
|
||||
$this->buildLogger->logFailure($message, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a configured instance of the plugin factory.
|
||||
*
|
||||
* @param Build $build
|
||||
* @return Factory
|
||||
* @return PluginFactory
|
||||
*/
|
||||
private function buildPluginFactory(Build $build)
|
||||
{
|
||||
$pluginFactory = new Factory();
|
||||
$pluginFactory = new PluginFactory();
|
||||
|
||||
$self = $this;
|
||||
$pluginFactory->registerResource(
|
||||
function () use($self) {
|
||||
function () use ($self) {
|
||||
return $self;
|
||||
},
|
||||
null,
|
||||
|
@ -418,7 +352,7 @@ class Builder implements LoggerAwareInterface, BuildLogger
|
|||
);
|
||||
|
||||
$pluginFactory->registerResource(
|
||||
function () use($build) {
|
||||
function () use ($build) {
|
||||
return $build;
|
||||
},
|
||||
null,
|
||||
|
|
130
PHPCI/Command/CreateAdminCommand.php
Normal file
130
PHPCI/Command/CreateAdminCommand.php
Normal file
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2013, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link http://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use b8\Store\Factory;
|
||||
use PHPCI\Builder;
|
||||
|
||||
/**
|
||||
* Create admin command - creates an admin user
|
||||
* @author Wogan May (@woganmay)
|
||||
* @package PHPCI
|
||||
* @subpackage Console
|
||||
*/
|
||||
class CreateAdminCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('phpci:create-admin')
|
||||
->setDescription('Create an admin user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an admin user in the existing PHPCI database
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
||||
require(PHPCI_DIR . 'bootstrap.php');
|
||||
|
||||
// Try to create a user account:
|
||||
$adminEmail = $this->ask('Admin email address: ', true, FILTER_VALIDATE_EMAIL);
|
||||
|
||||
if (empty($adminEmail)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$adminPass = $this->ask('Admin password: ');
|
||||
$adminName = $this->ask('Admin name: ');
|
||||
|
||||
try {
|
||||
$user = new \PHPCI\Model\User();
|
||||
$user->setEmail($adminEmail);
|
||||
$user->setName($adminName);
|
||||
$user->setIsAdmin(1);
|
||||
$user->setHash(password_hash($adminPass, PASSWORD_DEFAULT));
|
||||
|
||||
$store = \b8\Store\Factory::getStore('User');
|
||||
$store->save($user);
|
||||
|
||||
print 'User account created!' . PHP_EOL;
|
||||
} catch (\Exception $ex) {
|
||||
print 'There was a problem creating your account. :(' . PHP_EOL;
|
||||
print $ex->getMessage();
|
||||
print PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
protected function ask($question, $emptyOk = false, $validationFilter = null)
|
||||
{
|
||||
print $question . ' ';
|
||||
|
||||
$rtn = '';
|
||||
$stdin = fopen('php://stdin', 'r');
|
||||
$rtn = fgets($stdin);
|
||||
fclose($stdin);
|
||||
|
||||
$rtn = trim($rtn);
|
||||
|
||||
if (!$emptyOk && empty($rtn)) {
|
||||
$rtn = $this->ask($question, $emptyOk, $validationFilter);
|
||||
} elseif ($validationFilter != null && ! empty($rtn)) {
|
||||
if (! $this -> controlFormat($rtn, $validationFilter, $statusMessage)) {
|
||||
print $statusMessage;
|
||||
$rtn = $this->ask($question, $emptyOk, $validationFilter);
|
||||
}
|
||||
}
|
||||
|
||||
return $rtn;
|
||||
}
|
||||
protected function controlFormat($valueToInspect, $filter, &$statusMessage)
|
||||
{
|
||||
$filters = !(is_array($filter))? array($filter) : $filter;
|
||||
$statusMessage = '';
|
||||
$status = true;
|
||||
$options = array();
|
||||
|
||||
foreach ($filters as $filter) {
|
||||
if (! is_int($filter)) {
|
||||
$regexp = $filter;
|
||||
$filter = FILTER_VALIDATE_REGEXP;
|
||||
$options = array(
|
||||
'options' => array(
|
||||
'regexp' => $regexp,
|
||||
)
|
||||
);
|
||||
}
|
||||
if (! filter_var($valueToInspect, $filter, $options)) {
|
||||
$status = false;
|
||||
|
||||
switch ($filter)
|
||||
{
|
||||
case FILTER_VALIDATE_URL:
|
||||
$statusMessage = 'Incorrect url format.' . PHP_EOL;
|
||||
break;
|
||||
case FILTER_VALIDATE_EMAIL:
|
||||
$statusMessage = 'Incorrect e-mail format.' . PHP_EOL;
|
||||
break;
|
||||
case FILTER_VALIDATE_REGEXP:
|
||||
$statusMessage = 'Incorrect format.' . PHP_EOL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
|
@ -10,14 +10,13 @@
|
|||
|
||||
namespace PHPCI\Command;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use b8\Store\Factory;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\BuildFactory;
|
||||
|
||||
/**
|
||||
* Daemon that loops and call the run-command.
|
||||
|
@ -27,6 +26,36 @@ use PHPCI\BuildFactory;
|
|||
*/
|
||||
class DaemoniseCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @var Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $run;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $sleep;
|
||||
|
||||
/**
|
||||
* @param \Monolog\Logger $logger
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(Logger $logger, $name = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
|
@ -43,14 +72,19 @@ class DaemoniseCommand extends Command
|
|||
$command = sprintf($cmd, getmypid(), PHPCI_DIR);
|
||||
exec($command);
|
||||
|
||||
$this->output = $output;
|
||||
$this->run = true;
|
||||
$this->sleep = 0;
|
||||
$runner = new RunCommand;
|
||||
$runner = new RunCommand($this->logger);
|
||||
|
||||
$emptyInput = new ArgvInput(array());
|
||||
|
||||
while ($this->run) {
|
||||
|
||||
$buildCount = 0;
|
||||
|
||||
try {
|
||||
$buildCount = $runner->execute($input, $output);
|
||||
$buildCount = $runner->run($emptyInput, $output);
|
||||
} catch (\Exception $e) {
|
||||
var_dump($e);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class GenerateCommand extends Command
|
|||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$gen = new CodeGenerator(Database::getConnection(), 'PHPCI', PHPCI_DIR . '/PHPCI/', false);
|
||||
$gen = new CodeGenerator(Database::getConnection(), ['default' => 'PHPCI'], ['default' => PHPCI_DIR], false);
|
||||
$gen->generateModels();
|
||||
$gen->generateStores();
|
||||
}
|
||||
|
|
|
@ -80,7 +80,9 @@ class PollCommand extends Command
|
|||
$this->logger->info("Last commit to github for " . $project->getTitle() . " is " . $last_commit);
|
||||
|
||||
if ($project->getLastCommit() != $last_commit && $last_commit != "") {
|
||||
$this->logger->info("Last commit is different from database, adding new build for " . $project->getTitle());
|
||||
$this->logger->info(
|
||||
"Last commit is different from database, adding new build for " . $project->getTitle()
|
||||
);
|
||||
|
||||
$build = new Build();
|
||||
$build->setProjectId($project->getId());
|
||||
|
@ -101,4 +103,3 @@ class PollCommand extends Command
|
|||
$this->logger->addInfo("Finished processing builds");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
namespace PHPCI\Command;
|
||||
|
||||
use Monolog\Logger;
|
||||
use PHPCI\Helper\BuildDBLogHandler;
|
||||
use PHPCI\Helper\LoggedBuildContextTidier;
|
||||
use PHPCI\Helper\OutputLogHandler;
|
||||
use PHPCI\Logging\BuildDBLogHandler;
|
||||
use PHPCI\Logging\LoggedBuildContextTidier;
|
||||
use PHPCI\Logging\OutputLogHandler;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
@ -22,6 +22,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
use b8\Store\Factory;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\BuildFactory;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* Run console command - Runs any pending builds.
|
||||
|
@ -88,17 +89,24 @@ class RunCommand extends Command
|
|||
|
||||
$build = BuildFactory::getBuild($build);
|
||||
|
||||
// Logging relevant to this build should be stored
|
||||
// against the build itself.
|
||||
$buildDbLog = new BuildDBLogHandler($build, Logger::INFO);
|
||||
$this->logger->pushHandler($buildDbLog);
|
||||
try {
|
||||
// Logging relevant to this build should be stored
|
||||
// against the build itself.
|
||||
$buildDbLog = new BuildDBLogHandler($build, Logger::INFO);
|
||||
$this->logger->pushHandler($buildDbLog);
|
||||
|
||||
$builder = new Builder($build, $this->logger);
|
||||
$builder->execute();
|
||||
$builder = new Builder($build, $this->logger);
|
||||
$builder->execute();
|
||||
|
||||
// After execution we no longer want to record the information
|
||||
// back to this specific build so the handler should be removed.
|
||||
$this->logger->popHandler($buildDbLog);
|
||||
} catch (\Exception $ex) {
|
||||
$build->setStatus(Build::STATUS_FAILED);
|
||||
$build->setLog($build->getLog() . PHP_EOL . PHP_EOL . $ex->getMessage());
|
||||
$store->save($build);
|
||||
}
|
||||
|
||||
// After execution we no longer want to record the information
|
||||
// back to this specific build so the handler should be removed.
|
||||
$this->logger->popHandler($buildDbLog);
|
||||
}
|
||||
|
||||
$this->logger->addInfo("Finished processing builds");
|
||||
|
|
|
@ -38,7 +38,7 @@ class Controller extends \b8\Controller
|
|||
if (View::exists($this->className)) {
|
||||
$this->controllerView = new View($this->className);
|
||||
} else {
|
||||
$this->controllerView = new View\UserView('{@content}');
|
||||
$this->controllerView = new View\Template('{@content}');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2013, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link http://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use b8\Store;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* BitBucket Controller - Processes webhook pings from BitBucket.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Web
|
||||
*/
|
||||
class BitbucketController extends \PHPCI\Controller
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Store\BuildStore
|
||||
*/
|
||||
protected $buildStore;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->buildStore = Store\Factory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Bitbucket POST service.
|
||||
*/
|
||||
public function webhook($project)
|
||||
{
|
||||
$payload = json_decode($this->getParam('payload'), true);
|
||||
$branches = array();
|
||||
$commits = array();
|
||||
|
||||
foreach ($payload['commits'] as $commit) {
|
||||
if (!in_array($commit['branch'], $branches)) {
|
||||
$branches[] = $commit['branch'];
|
||||
$commits[$commit['branch']] = $commit['raw_node'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($branches as $branch) {
|
||||
try {
|
||||
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
$build->setCommitId($commits[$branch]);
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setBranch($branch);
|
||||
$this->buildStore->save($build);
|
||||
} catch (\Exception $ex) {
|
||||
}
|
||||
}
|
||||
|
||||
die('OK');
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use PHPCI\BuildFactory;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
|
@ -35,7 +36,7 @@ class BuildController extends \PHPCI\Controller
|
|||
*/
|
||||
public function view($buildId)
|
||||
{
|
||||
$build = $this->buildStore->getById($buildId);
|
||||
$build = BuildFactory::getBuildById($buildId);
|
||||
$this->view->plugins = $this->getUiPlugins();
|
||||
$this->view->build = $build;
|
||||
$this->view->data = $this->getBuildData($build);
|
||||
|
@ -63,7 +64,7 @@ class BuildController extends \PHPCI\Controller
|
|||
*/
|
||||
public function data($buildId)
|
||||
{
|
||||
die($this->getBuildData($this->buildStore->getById($buildId)));
|
||||
die($this->getBuildData(BuildFactory::getBuildById($buildId)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +72,7 @@ class BuildController extends \PHPCI\Controller
|
|||
*/
|
||||
public function meta($buildId)
|
||||
{
|
||||
$build = $this->buildStore->getById($buildId);
|
||||
$build = BuildFactory::getBuildById($buildId);
|
||||
$key = $this->getParam('key', null);
|
||||
$numBuilds = $this->getParam('num_builds', 1);
|
||||
$data = null;
|
||||
|
@ -104,7 +105,7 @@ class BuildController extends \PHPCI\Controller
|
|||
*/
|
||||
public function rebuild($buildId)
|
||||
{
|
||||
$copy = $this->buildStore->getById($buildId);
|
||||
$copy = BuildFactory::getBuildById($buildId);
|
||||
|
||||
$build = new Build();
|
||||
$build->setProjectId($copy->getProjectId());
|
||||
|
@ -112,6 +113,8 @@ class BuildController extends \PHPCI\Controller
|
|||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setBranch($copy->getBranch());
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setCommitterEmail($copy->getCommitterEmail());
|
||||
$build->setCommitMessage($copy->getCommitMessage());
|
||||
|
||||
$build = $this->buildStore->save($build);
|
||||
|
||||
|
@ -128,7 +131,7 @@ class BuildController extends \PHPCI\Controller
|
|||
throw new \Exception('You do not have permission to do that.');
|
||||
}
|
||||
|
||||
$build = $this->buildStore->getById($buildId);
|
||||
$build = BuildFactory::getBuildById($buildId);
|
||||
|
||||
if (!$build) {
|
||||
$this->response->setResponseCode(404);
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2013, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link http://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use b8\Store;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* @author Sami Tikka <stikka@iki.fi>
|
||||
*/
|
||||
class GitController extends \PHPCI\Controller
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
$this->_buildStore = Store\Factory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by POSTing to /git/webhook/<project_id>?branch=<branch>&commit=<commit>
|
||||
*
|
||||
* @param string $project
|
||||
*/
|
||||
public function webhook($project)
|
||||
{
|
||||
$branch = $this->getParam('branch');
|
||||
$commit = $this->getParam('commit');
|
||||
|
||||
try {
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
|
||||
if ($branch !== null && trim($branch) !== '') {
|
||||
$build->setBranch($branch);
|
||||
} else {
|
||||
$build->setBranch('master');
|
||||
}
|
||||
|
||||
if ($commit !== null && trim($commit) !== '') {
|
||||
$build->setCommitId($commit);
|
||||
}
|
||||
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->_buildStore->save($build);
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
die('OK');
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2013, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link http://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use b8\Store;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* Github Controller - Processes webhook pings from Github.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Web
|
||||
*/
|
||||
class GithubController extends \PHPCI\Controller
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Store\BuildStore
|
||||
*/
|
||||
protected $buildStore;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->buildStore = Store\Factory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Github Webhooks:
|
||||
*/
|
||||
public function webhook($project)
|
||||
{
|
||||
$payload = json_decode($this->getParam('payload'), true);
|
||||
|
||||
// Github sends a payload when you close a pull request with a
|
||||
// non-existant commit. We don't want this.
|
||||
if ($payload['after'] === '0000000000000000000000000000000000000000') {
|
||||
die('OK');
|
||||
}
|
||||
|
||||
try {
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
$build->setCommitId($payload['after']);
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setBranch(str_replace('refs/heads/', '', $payload['ref']));
|
||||
|
||||
if (!empty($payload['pusher']['email'])) {
|
||||
$build->setCommitterEmail($payload['pusher']['email']);
|
||||
}
|
||||
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
try {
|
||||
$build = $this->buildStore->save($build);
|
||||
$build->sendStatusPostback();
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
die('OK');
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2013, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link http://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use b8\Store;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* Gitlab Controller - Processes webhook pings from Gitlab.
|
||||
* @author Alex Russell <alex@clevercherry.com>, Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Web
|
||||
*/
|
||||
class GitlabController extends \PHPCI\Controller
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Store\BuildStore
|
||||
*/
|
||||
protected $buildStore;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->buildStore = Store\Factory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Gitlab Webhooks:
|
||||
*/
|
||||
public function webhook($project)
|
||||
{
|
||||
$payload = json_decode(file_get_contents("php://input"), true);
|
||||
|
||||
try {
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
$build->setCommitId($payload['after']);
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setBranch(str_replace('refs/heads/', '', $payload['ref']));
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
try {
|
||||
$build = $this->buildStore->save($build);
|
||||
$build->sendStatusPostback();
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
die('OK');
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use PHPCI\BuildFactory;
|
||||
|
||||
/**
|
||||
* Home Controller - Displays the PHPCI Dashboard.
|
||||
|
@ -73,6 +74,11 @@ class HomeController extends \PHPCI\Controller
|
|||
{
|
||||
$builds = $this->buildStore->getWhere(array(), 5, 0, array(), array('id' => 'DESC'));
|
||||
$view = new b8\View('BuildsTable');
|
||||
|
||||
foreach ($builds['items'] as &$build) {
|
||||
$build = BuildFactory::getBuild($build);
|
||||
}
|
||||
|
||||
$view->builds = $builds['items'];
|
||||
|
||||
return $view->render();
|
||||
|
|
|
@ -11,6 +11,9 @@ namespace PHPCI\Controller;
|
|||
|
||||
use b8;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Plugin\Util\ComposerPluginInformation;
|
||||
use PHPCI\Plugin\Util\FilesPluginInformation;
|
||||
use PHPCI\Plugin\Util\PluginInformationCollection;
|
||||
|
||||
/**
|
||||
* Plugin Controller - Provides support for installing Composer packages.
|
||||
|
@ -59,8 +62,18 @@ class PluginController extends \PHPCI\Controller
|
|||
$this->view->required = $this->required;
|
||||
|
||||
$json = $this->getComposerJson();
|
||||
$this->view->installed = $json['require'];
|
||||
$this->view->suggested = $json['suggest'];
|
||||
$this->view->installedPackages = $json['require'];
|
||||
$this->view->suggestedPackages = $json['suggest'];
|
||||
|
||||
$pluginInfo = new PluginInformationCollection();
|
||||
$pluginInfo->add(FilesPluginInformation::newFromDir(
|
||||
PHPCI_DIR . "PHPCI/Plugin/"
|
||||
));
|
||||
$pluginInfo->add(ComposerPluginInformation::buildFromYaml(
|
||||
PHPCI_DIR . "vendor/composer/installed.json"
|
||||
));
|
||||
|
||||
$this->view->plugins = $pluginInfo->getInstalledPlugins();
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
namespace PHPCI\Controller;
|
||||
|
||||
use PHPCI\BuildFactory;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Model\Project;
|
||||
use b8;
|
||||
|
@ -113,6 +114,11 @@ class ProjectController extends \PHPCI\Controller
|
|||
$order = array('id' => 'DESC');
|
||||
$builds = $this->buildStore->getWhere($criteria, 10, $start, array(), $order);
|
||||
$view = new b8\View('BuildsTable');
|
||||
|
||||
foreach ($builds['items'] as &$build) {
|
||||
$build = BuildFactory::getBuild($build);
|
||||
}
|
||||
|
||||
$view->builds = $builds['items'];
|
||||
|
||||
return array($view->render(), $builds['count']);
|
||||
|
|
206
PHPCI/Controller/WebhookController.php
Normal file
206
PHPCI/Controller/WebhookController.php
Normal file
|
@ -0,0 +1,206 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2013, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link http://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use b8\Store;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* Webhook Controller - Processes webhook pings from BitBucket, Github, Gitlab, etc.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @author Sami Tikka <stikka@iki.fi>
|
||||
* @author Alex Russell <alex@clevercherry.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Web
|
||||
*/
|
||||
class WebhookController extends \PHPCI\Controller
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Store\BuildStore
|
||||
*/
|
||||
protected $buildStore;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->buildStore = Store\Factory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Bitbucket POST service.
|
||||
*/
|
||||
public function bitbucket($project)
|
||||
{
|
||||
$payload = json_decode($this->getParam('payload'), true);
|
||||
|
||||
foreach ($payload['commits'] as $commit) {
|
||||
try {
|
||||
$email = $commit['raw_author'];
|
||||
$email = substr($email, 0, strpos($email, '>'));
|
||||
$email = substr($email, strpos($email, '<') + 1);
|
||||
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
$build->setCommitId($commit['raw_node']);
|
||||
$build->setCommitterEmail($email);
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setBranch($commit['branch']);
|
||||
$build->setCommitMessage($commit['message']);
|
||||
$this->buildStore->save($build);
|
||||
} catch (\Exception $ex) {
|
||||
}
|
||||
}
|
||||
|
||||
die('OK');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by POSTing to /git/webhook/<project_id>?branch=<branch>&commit=<commit>
|
||||
*
|
||||
* @param string $project
|
||||
*/
|
||||
public function git($project)
|
||||
{
|
||||
$branch = $this->getParam('branch');
|
||||
$commit = $this->getParam('commit');
|
||||
|
||||
try {
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
|
||||
if ($branch !== null && trim($branch) !== '') {
|
||||
$build->setBranch($branch);
|
||||
} else {
|
||||
$build->setBranch('master');
|
||||
}
|
||||
|
||||
if ($commit !== null && trim($commit) !== '') {
|
||||
$build->setCommitId($commit);
|
||||
}
|
||||
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->_buildStore->save($build);
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
die('OK');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Github Webhooks:
|
||||
*/
|
||||
public function github($project)
|
||||
{
|
||||
$payload = json_decode($this->getParam('payload'), true);
|
||||
|
||||
// Github sends a payload when you close a pull request with a
|
||||
// non-existant commit. We don't want this.
|
||||
if ($payload['after'] === '0000000000000000000000000000000000000000') {
|
||||
die('OK');
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if (isset($payload['commits']) && is_array($payload['commits'])) {
|
||||
// If we have a list of commits, then add them all as builds to be tested:
|
||||
|
||||
foreach ($payload['commits'] as $commit) {
|
||||
if (!$commit['distinct']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
$build->setCommitId($commit['id']);
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setBranch(str_replace('refs/heads/', '', $payload['ref']));
|
||||
$build->setCommitterEmail($commit['committer']['email']);
|
||||
$build->setCommitMessage($commit['message']);
|
||||
$build = $this->buildStore->save($build);
|
||||
$build->sendStatusPostback();
|
||||
}
|
||||
} elseif (substr($payload['ref'], 0, 10) == 'refs/tags/') {
|
||||
// If we don't, but we're dealing with a tag, add that instead:
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
$build->setCommitId($payload['after']);
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setBranch(str_replace('refs/tags/', 'Tag: ', $payload['ref']));
|
||||
$build->setCommitterEmail($payload['pusher']['email']);
|
||||
$build->setCommitMessage($payload['head_commit']['message']);
|
||||
|
||||
$build = $this->buildStore->save($build);
|
||||
$build->sendStatusPostback();
|
||||
}
|
||||
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
die('OK');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Gitlab Webhooks:
|
||||
*/
|
||||
public function gitlab($project)
|
||||
{
|
||||
$payloadString = file_get_contents("php://input");
|
||||
$payload = json_decode($payloadString, true);
|
||||
|
||||
try {
|
||||
|
||||
if (isset($payload['commits']) && is_array($payload['commits'])) {
|
||||
// If we have a list of commits, then add them all as builds to be tested:
|
||||
|
||||
foreach ($payload['commits'] as $commit) {
|
||||
$build = new Build();
|
||||
$build->setProjectId($project);
|
||||
$build->setCommitId($commit['id']);
|
||||
$build->setStatus(Build::STATUS_NEW);
|
||||
$build->setLog('');
|
||||
$build->setCreated(new \DateTime());
|
||||
$build->setBranch(str_replace('refs/heads/', '', $payload['ref']));
|
||||
$build->setCommitterEmail($commit['author']['email']);
|
||||
$build->setCommitMessage($commit['message']);
|
||||
$build = $this->buildStore->save($build);
|
||||
$build->sendStatusPostback();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (\Exception $ex) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
header('Ex: ' . $ex->getMessage());
|
||||
die('FAIL');
|
||||
}
|
||||
|
||||
die('OK');
|
||||
}
|
||||
}
|
61
PHPCI/Helper/BuildInterpolator.php
Normal file
61
PHPCI/Helper/BuildInterpolator.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Helper;
|
||||
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
class BuildInterpolator
|
||||
{
|
||||
/**
|
||||
* An array of key => value pairs that will be used for
|
||||
* interpolation and environment variables
|
||||
* @var mixed[]
|
||||
* @see setupInterpolationVars()
|
||||
*/
|
||||
protected $interpolation_vars = array();
|
||||
|
||||
/**
|
||||
* Sets the variables that will be used for interpolation.
|
||||
* @param Build $build
|
||||
* @param string $buildPath
|
||||
* @param string $phpCiUrl
|
||||
*/
|
||||
public function setupInterpolationVars(Build $build, $buildPath, $phpCiUrl)
|
||||
{
|
||||
$this->interpolation_vars = array();
|
||||
$this->interpolation_vars['%PHPCI%'] = 1;
|
||||
$this->interpolation_vars['%COMMIT%'] = $build->getCommitId();
|
||||
$this->interpolation_vars['%PROJECT%'] = $build->getProjectId();
|
||||
$this->interpolation_vars['%BUILD%'] = $build->getId();
|
||||
$this->interpolation_vars['%PROJECT_TITLE%'] = $build->getProjectTitle();
|
||||
$this->interpolation_vars['%BUILD_PATH%'] = $buildPath;
|
||||
$this->interpolation_vars['%BUILD_URI%'] = $phpCiUrl . "build/view/" . $build->getId();
|
||||
$this->interpolation_vars['%PHPCI_COMMIT%'] = $this->interpolation_vars['%COMMIT%'];
|
||||
$this->interpolation_vars['%PHPCI_PROJECT%'] = $this->interpolation_vars['%PROJECT%'];
|
||||
$this->interpolation_vars['%PHPCI_BUILD%'] = $this->interpolation_vars['%BUILD%'];
|
||||
$this->interpolation_vars['%PHPCI_PROJECT_TITLE%'] = $this->interpolation_vars['%PROJECT_TITLE%'];
|
||||
$this->interpolation_vars['%PHPCI_BUILD_PATH%'] = $this->interpolation_vars['%BUILD_PATH%'];
|
||||
$this->interpolation_vars['%PHPCI_BUILD_URI%'] = $this->interpolation_vars['%BUILD_URI%'];
|
||||
|
||||
putenv('PHPCI=1');
|
||||
putenv('PHPCI_COMMIT=' . $this->interpolation_vars['%COMMIT%']);
|
||||
putenv('PHPCI_PROJECT=' . $this->interpolation_vars['%PROJECT%']);
|
||||
putenv('PHPCI_BUILD=' . $this->interpolation_vars['%BUILD%']);
|
||||
putenv('PHPCI_PROJECT_TITLE=' . $this->interpolation_vars['%PROJECT_TITLE%']);
|
||||
putenv('PHPCI_BUILD_PATH=' . $this->interpolation_vars['%BUILD_PATH%']);
|
||||
putenv('PHPCI_BUILD_URI=' . $this->interpolation_vars['%BUILD_URI%']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace every occurrence of the interpolation vars in the given string
|
||||
* Example: "This is build %PHPCI_BUILD%" => "This is build 182"
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public function interpolate($input)
|
||||
{
|
||||
$keys = array_keys($this->interpolation_vars);
|
||||
$values = array_values($this->interpolation_vars);
|
||||
return str_replace($keys, $values, $input);
|
||||
}
|
||||
}
|
|
@ -3,12 +3,13 @@
|
|||
namespace PHPCI\Helper;
|
||||
|
||||
|
||||
use PHPCI\BuildLogger;
|
||||
use \PHPCI\Logging\BuildLogger;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class CommandExecutor
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\BuildLogger
|
||||
* @var \PHPCI\Logging\BuildLogger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
|
@ -75,6 +76,10 @@ class CommandExecutor
|
|||
$status = 0;
|
||||
exec($command, $this->lastOutput, $status);
|
||||
|
||||
foreach ($this->lastOutput as &$lastOutput) {
|
||||
$lastOutput = trim($lastOutput, '"');
|
||||
}
|
||||
|
||||
if (!empty($this->lastOutput) && ($this->verbose|| $status != 0)) {
|
||||
$this->logger->log($this->lastOutput);
|
||||
}
|
||||
|
@ -108,21 +113,26 @@ class CommandExecutor
|
|||
}
|
||||
|
||||
foreach ($binary as $bin) {
|
||||
$this->logger->log("Looking for binary: " . $bin, LogLevel::DEBUG);
|
||||
// Check project root directory:
|
||||
if (is_file($this->rootDir . $bin)) {
|
||||
$this->logger->log("Found in root: " . $bin, LogLevel::DEBUG);
|
||||
return $this->rootDir . $bin;
|
||||
}
|
||||
|
||||
// Check Composer bin dir:
|
||||
if (is_file($this->rootDir . 'vendor/bin/' . $bin)) {
|
||||
$this->logger->log("Found in vendor/bin: " . $bin, LogLevel::DEBUG);
|
||||
return $this->rootDir . 'vendor/bin/' . $bin;
|
||||
}
|
||||
|
||||
// Use "which"
|
||||
$which = trim(shell_exec('which ' . $bin));
|
||||
// Use "where" for windows and "which" for other OS
|
||||
$findCmd = (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') ? 'which' : 'where';
|
||||
$findCmdResult = trim(shell_exec($findCmd . ' ' . $bin));
|
||||
|
||||
if (!empty($which)) {
|
||||
return $which;
|
||||
if (!empty($findCmdResult)) {
|
||||
$this->logger->log("Found in " . $findCmdResult, LogLevel::DEBUG);
|
||||
return $findCmdResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Helper;
|
||||
namespace PHPCI\Logging;
|
||||
|
||||
|
||||
use b8\Store;
|
||||
|
@ -16,7 +16,7 @@ class BuildDBLogHandler extends AbstractProcessingHandler
|
|||
|
||||
protected $logValue;
|
||||
|
||||
function __construct(
|
||||
public function __construct(
|
||||
Build $build,
|
||||
$level = LogLevel::INFO,
|
||||
$bubble = true
|
||||
|
@ -29,7 +29,10 @@ class BuildDBLogHandler extends AbstractProcessingHandler
|
|||
|
||||
protected function write(array $record)
|
||||
{
|
||||
$this->logValue .= (string)$record['formatted'];
|
||||
$message = (string)$record['message'];
|
||||
$message = str_replace($this->build->currentBuildPath, '/', $message);
|
||||
|
||||
$this->logValue .= $message . PHP_EOL;
|
||||
$this->build->setLog($this->logValue);
|
||||
}
|
||||
}
|
||||
}
|
96
PHPCI/Logging/BuildLogger.php
Normal file
96
PHPCI/Logging/BuildLogger.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Logging;
|
||||
|
||||
|
||||
use PHPCI\Model\Build;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class BuildLogger implements LoggerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* @var Build
|
||||
*/
|
||||
protected $build;
|
||||
|
||||
public function __construct(LoggerInterface $logger, Build $build)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->build = $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an entry to the build log.
|
||||
* @param string|string[] $message
|
||||
* @param string $level
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function log($message, $level = LogLevel::INFO, $context = array())
|
||||
{
|
||||
// Skip if no logger has been loaded.
|
||||
if (!$this->logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_array($message)) {
|
||||
$message = array($message);
|
||||
}
|
||||
|
||||
// The build is added to the context so the logger can use
|
||||
// details from it if required.
|
||||
$context['build'] = $this->build;
|
||||
|
||||
foreach ($message as $item) {
|
||||
$this->logger->log($level, $item, $context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a success-coloured message to the log.
|
||||
* @param string
|
||||
*/
|
||||
public function logSuccess($message)
|
||||
{
|
||||
$this->log("\033[0;32m" . $message . "\033[0m");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a failure-coloured message to the log.
|
||||
* @param string $message
|
||||
* @param \Exception $exception The exception that caused the error.
|
||||
*/
|
||||
public function logFailure($message, \Exception $exception = null)
|
||||
{
|
||||
$context = array();
|
||||
|
||||
// The psr3 log interface stipulates that exceptions should be passed
|
||||
// as the exception key in the context array.
|
||||
if ($exception) {
|
||||
$context['exception'] = $exception;
|
||||
}
|
||||
|
||||
$this->log(
|
||||
"\033[0;31m" . $message . "\033[0m",
|
||||
LogLevel::ERROR,
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a logger instance on the object
|
||||
*
|
||||
* @param LoggerInterface $logger
|
||||
* @return null
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Helper;
|
||||
namespace PHPCI\Logging;
|
||||
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
class LoggedBuildContextTidier
|
||||
{
|
||||
function __invoke()
|
||||
public function __invoke()
|
||||
{
|
||||
return $this->tidyLoggedBuildContext(func_get_arg(0));
|
||||
}
|
||||
|
@ -29,4 +29,4 @@ class LoggedBuildContextTidier
|
|||
}
|
||||
return $logRecord;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,15 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace PHPCI\Helper;
|
||||
namespace PHPCI\Logging;
|
||||
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class LoggerConfig {
|
||||
class LoggerConfig
|
||||
{
|
||||
|
||||
const KEY_AlwaysLoaded = "_";
|
||||
const KEY_ALWAYS_LOADED = "_";
|
||||
|
||||
private $config;
|
||||
|
||||
|
@ -23,8 +24,7 @@ class LoggerConfig {
|
|||
{
|
||||
if (file_exists($filePath)) {
|
||||
$configArray = require($filePath);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$configArray = array();
|
||||
}
|
||||
return new self($configArray);
|
||||
|
@ -36,7 +36,8 @@ class LoggerConfig {
|
|||
* array of LogHandlers.
|
||||
* @param array $configArray
|
||||
*/
|
||||
function __construct(array $configArray = array()) {
|
||||
public function __construct(array $configArray = array())
|
||||
{
|
||||
$this->config = $configArray;
|
||||
}
|
||||
|
||||
|
@ -46,13 +47,15 @@ class LoggerConfig {
|
|||
* @param $name
|
||||
* @return Logger
|
||||
*/
|
||||
public function getFor($name) {
|
||||
$handlers = $this->getHandlers(self::KEY_AlwaysLoaded);
|
||||
public function getFor($name)
|
||||
{
|
||||
$handlers = $this->getHandlers(self::KEY_ALWAYS_LOADED);
|
||||
$handlers = array_merge($handlers, $this->getHandlers($name));
|
||||
return new Logger($name, $handlers);
|
||||
}
|
||||
|
||||
protected function getHandlers($key) {
|
||||
protected function getHandlers($key)
|
||||
{
|
||||
$handlers = array();
|
||||
|
||||
// They key is expected to either be an array or
|
||||
|
@ -60,12 +63,10 @@ class LoggerConfig {
|
|||
if (isset($this->config[$key])) {
|
||||
if (is_callable($this->config[$key])) {
|
||||
$handlers = call_user_func($this->config[$key]);
|
||||
}
|
||||
elseif(is_array($this->config[$key])) {
|
||||
} elseif (is_array($this->config[$key])) {
|
||||
$handlers = $this->config[$key];
|
||||
}
|
||||
}
|
||||
return $handlers;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Helper;
|
||||
namespace PHPCI\Logging;
|
||||
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
use Psr\Log\LogLevel;
|
||||
|
@ -14,7 +14,7 @@ class OutputLogHandler extends AbstractProcessingHandler
|
|||
*/
|
||||
protected $output;
|
||||
|
||||
function __construct(
|
||||
public function __construct(
|
||||
OutputInterface $output,
|
||||
$level = LogLevel::INFO,
|
||||
$bubble = true
|
||||
|
@ -30,4 +30,4 @@ class OutputLogHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
7
PHPCI/Model.php
Normal file
7
PHPCI/Model.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
namespace PHPCI;
|
||||
|
||||
abstract class Model extends \b8\Model
|
||||
{
|
||||
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace PHPCI\Model\Base;
|
||||
|
||||
use b8\Model;
|
||||
use PHPCI\Model;
|
||||
use b8\Store\Factory;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,7 @@ class BuildBase extends Model
|
|||
'finished' => null,
|
||||
'plugins' => null,
|
||||
'committer_email' => null,
|
||||
'commit_message' => null,
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -62,6 +63,7 @@ class BuildBase extends Model
|
|||
'finished' => 'getFinished',
|
||||
'plugins' => 'getPlugins',
|
||||
'committer_email' => 'getCommitterEmail',
|
||||
'commit_message' => 'getCommitMessage',
|
||||
|
||||
// Foreign key getters:
|
||||
'Project' => 'getProject',
|
||||
|
@ -83,6 +85,7 @@ class BuildBase extends Model
|
|||
'finished' => 'setFinished',
|
||||
'plugins' => 'setPlugins',
|
||||
'committer_email' => 'setCommitterEmail',
|
||||
'commit_message' => 'setCommitMessage',
|
||||
|
||||
// Foreign key setters:
|
||||
'Project' => 'setProject',
|
||||
|
@ -113,6 +116,7 @@ class BuildBase extends Model
|
|||
'status' => array(
|
||||
'type' => 'tinyint',
|
||||
'length' => 4,
|
||||
'default' => null,
|
||||
),
|
||||
'log' => array(
|
||||
'type' => 'longtext',
|
||||
|
@ -150,6 +154,11 @@ class BuildBase extends Model
|
|||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
'commit_message' => array(
|
||||
'type' => 'text',
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -318,6 +327,18 @@ class BuildBase extends Model
|
|||
return $rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of CommitMessage / commit_message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCommitMessage()
|
||||
{
|
||||
$rtn = $this->data['commit_message'];
|
||||
|
||||
return $rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of Id / id.
|
||||
*
|
||||
|
@ -524,6 +545,24 @@ class BuildBase extends Model
|
|||
$this->_setModified('committer_email');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of CommitMessage / commit_message.
|
||||
*
|
||||
* @param $value string
|
||||
*/
|
||||
public function setCommitMessage($value)
|
||||
{
|
||||
$this->_validateString('CommitMessage', $value);
|
||||
|
||||
if ($this->data['commit_message'] === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->data['commit_message'] = $value;
|
||||
|
||||
$this->_setModified('commit_message');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Project model for this Build by Id.
|
||||
*
|
||||
|
@ -543,7 +582,7 @@ class BuildBase extends Model
|
|||
$rtn = $this->cache->get($cacheKey, null);
|
||||
|
||||
if (empty($rtn)) {
|
||||
$rtn = Factory::getStore('Project')->getById($key);
|
||||
$rtn = Factory::getStore('Project', 'PHPCI')->getById($key);
|
||||
$this->cache->set($cacheKey, $rtn);
|
||||
}
|
||||
|
||||
|
@ -590,6 +629,33 @@ class BuildBase extends Model
|
|||
*/
|
||||
public function getBuildBuildMetas()
|
||||
{
|
||||
return Factory::getStore('BuildMeta')->getByBuildId($this->getId());
|
||||
return Factory::getStore('BuildMeta', 'PHPCI')->getByBuildId($this->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function getByPrimaryKey($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('Build', 'PHPCI')->getByPrimaryKey($value, $useConnection);
|
||||
}
|
||||
|
||||
|
||||
public static function getById($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('Build', 'PHPCI')->getById($value, $useConnection);
|
||||
}
|
||||
|
||||
public static function getByProjectId($value, $limit = null, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('Build', 'PHPCI')->getByProjectId($value, $limit, $useConnection);
|
||||
}
|
||||
|
||||
public static function getByStatus($value, $limit = null, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('Build', 'PHPCI')->getByStatus($value, $limit, $useConnection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace PHPCI\Model\Base;
|
||||
|
||||
use b8\Model;
|
||||
use PHPCI\Model;
|
||||
use b8\Store\Factory;
|
||||
|
||||
/**
|
||||
|
@ -95,6 +95,7 @@ class BuildMetaBase extends Model
|
|||
'meta_key' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'default' => null,
|
||||
),
|
||||
'meta_value' => array(
|
||||
'type' => 'text',
|
||||
|
@ -299,7 +300,7 @@ class BuildMetaBase extends Model
|
|||
$rtn = $this->cache->get($cacheKey, null);
|
||||
|
||||
if (empty($rtn)) {
|
||||
$rtn = Factory::getStore('Build')->getById($key);
|
||||
$rtn = Factory::getStore('Build', 'PHPCI')->getById($key);
|
||||
$this->cache->set($cacheKey, $rtn);
|
||||
}
|
||||
|
||||
|
@ -336,4 +337,26 @@ class BuildMetaBase extends Model
|
|||
{
|
||||
return $this->setBuildId($value->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function getByPrimaryKey($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('BuildMeta', 'PHPCI')->getByPrimaryKey($value, $useConnection);
|
||||
}
|
||||
|
||||
|
||||
public static function getById($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('BuildMeta', 'PHPCI')->getById($value, $useConnection);
|
||||
}
|
||||
|
||||
public static function getByBuildId($value, $limit = null, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('BuildMeta', 'PHPCI')->getByBuildId($value, $limit, $useConnection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace PHPCI\Model\Base;
|
||||
|
||||
use b8\Model;
|
||||
use PHPCI\Model;
|
||||
use b8\Store\Factory;
|
||||
|
||||
/**
|
||||
|
@ -91,10 +91,12 @@ class ProjectBase extends Model
|
|||
'title' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 250,
|
||||
'default' => null,
|
||||
),
|
||||
'reference' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 250,
|
||||
'default' => null,
|
||||
),
|
||||
'git_key' => array(
|
||||
'type' => 'text',
|
||||
|
@ -215,19 +217,11 @@ class ProjectBase extends Model
|
|||
/**
|
||||
* Get the value of AccessInformation / access_information.
|
||||
*
|
||||
* @param string|null $key Key of desired information
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAccessInformation($key = null)
|
||||
public function getAccessInformation()
|
||||
{
|
||||
if (is_null($key)) {
|
||||
$rtn = $this->data['access_information'];
|
||||
} else if (isset($this->data['access_information'][$key])) {
|
||||
$rtn = $this->data['access_information'][$key];
|
||||
} else {
|
||||
$rtn = null;
|
||||
}
|
||||
$rtn = $this->data['access_information'];
|
||||
|
||||
return $rtn;
|
||||
}
|
||||
|
@ -405,6 +399,28 @@ class ProjectBase extends Model
|
|||
*/
|
||||
public function getProjectBuilds()
|
||||
{
|
||||
return Factory::getStore('Build')->getByProjectId($this->getId());
|
||||
return Factory::getStore('Build', 'PHPCI')->getByProjectId($this->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function getByPrimaryKey($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('Project', 'PHPCI')->getByPrimaryKey($value, $useConnection);
|
||||
}
|
||||
|
||||
|
||||
public static function getById($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('Project', 'PHPCI')->getById($value, $useConnection);
|
||||
}
|
||||
|
||||
public static function getByTitle($value, $limit = null, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('Project', 'PHPCI')->getByTitle($value, $limit, $useConnection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace PHPCI\Model\Base;
|
||||
|
||||
use b8\Model;
|
||||
use PHPCI\Model;
|
||||
use b8\Store\Factory;
|
||||
|
||||
/**
|
||||
|
@ -82,14 +82,17 @@ class UserBase extends Model
|
|||
'email' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 250,
|
||||
'default' => null,
|
||||
),
|
||||
'hash' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 250,
|
||||
'default' => null,
|
||||
),
|
||||
'is_admin' => array(
|
||||
'type' => 'tinyint',
|
||||
'length' => 1,
|
||||
'default' => null,
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
|
@ -270,4 +273,26 @@ class UserBase extends Model
|
|||
|
||||
$this->_setModified('name');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function getByPrimaryKey($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('User', 'PHPCI')->getByPrimaryKey($value, $useConnection);
|
||||
}
|
||||
|
||||
|
||||
public static function getById($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('User', 'PHPCI')->getById($value, $useConnection);
|
||||
}
|
||||
|
||||
public static function getByEmail($value, $useConnection = 'read')
|
||||
{
|
||||
return Factory::getStore('User', 'PHPCI')->getByEmail($value, $useConnection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ class Build extends BuildBase
|
|||
const STATUS_SUCCESS = 2;
|
||||
const STATUS_FAILED = 3;
|
||||
|
||||
public $currentBuildPath = null;
|
||||
|
||||
/**
|
||||
* Get link to commit from another source (i.e. Github)
|
||||
*/
|
||||
|
@ -34,6 +36,15 @@ class Build extends BuildBase
|
|||
return '#';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProjectTitle()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
return $project ? $project->getTitle() : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to branch from another source (i.e. Github)
|
||||
*/
|
||||
|
|
|
@ -35,8 +35,7 @@ class RemoteGitBuild extends Build
|
|||
public function createWorkingCopy(Builder $builder, $buildPath)
|
||||
{
|
||||
$yamlParser = new YamlParser();
|
||||
$success = true;
|
||||
$key = trim($this->getProject()->getGitKey());
|
||||
$key = trim($this->getProject()->getGitKey());
|
||||
|
||||
if (!empty($key)) {
|
||||
$success = $this->cloneBySsh($builder, $buildPath);
|
||||
|
@ -65,7 +64,9 @@ class RemoteGitBuild extends Build
|
|||
*/
|
||||
protected function cloneByHttp(Builder $builder, $cloneTo)
|
||||
{
|
||||
return $builder->executeCommand('git clone -b %s %s "%s"', $this->getBranch(), $this->getCloneUrl(), $cloneTo);
|
||||
$success = $builder->executeCommand('git clone -b %s %s "%s"', $this->getBranch(), $this->getCloneUrl(), $cloneTo);
|
||||
$builder->executeCommand('cd "%s" && git checkout %s', $cloneTo, $this->getCommitId());
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,7 +89,13 @@ class RemoteGitBuild extends Build
|
|||
// Use the key file to do an SSH clone:
|
||||
$cmd = 'eval `ssh-agent -s` && ssh-add "%s" && git clone -b %s %s "%s" && ssh-agent -k';
|
||||
$success = $builder->executeCommand($cmd, $keyFile, $this->getBranch(), $this->getCloneUrl(), $cloneTo);
|
||||
|
||||
|
||||
$commit = $this->getCommitId();
|
||||
|
||||
if (!empty($commit) && $commit != 'Manual') {
|
||||
$builder->executeCommand('cd "%s" && git checkout %s', $cloneTo, $this->getCommitId());
|
||||
}
|
||||
|
||||
// Remove the key file:
|
||||
unlink($keyFile);
|
||||
|
||||
|
|
|
@ -43,4 +43,19 @@ class Project extends ProjectBase
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAccessInformation($key = null)
|
||||
{
|
||||
$data = unserialize($this->data['access_information']);
|
||||
|
||||
if (is_null($key)) {
|
||||
$rtn = $data;
|
||||
} elseif (isset($data[$key])) {
|
||||
$rtn = $data[$key];
|
||||
} else {
|
||||
$rtn = null;
|
||||
}
|
||||
|
||||
return $rtn;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,12 @@ class Behat implements \PHPCI\Plugin
|
|||
$this->phpci = $phpci;
|
||||
$this->features = '';
|
||||
|
||||
if (isset($options['executable'])) {
|
||||
$this->executable = $options['executable'];
|
||||
} else {
|
||||
$this->executable = $this->phpci->findBinary('atoum');
|
||||
}
|
||||
|
||||
if (!empty($options['features'])) {
|
||||
$this->features = $options['features'];
|
||||
}
|
||||
|
@ -41,7 +47,7 @@ class Behat implements \PHPCI\Plugin
|
|||
$curdir = getcwd();
|
||||
chdir($this->phpci->buildPath);
|
||||
|
||||
$behat = $this->phpci->findBinary('behat');
|
||||
$behat = $this->executable;
|
||||
|
||||
if (!$behat) {
|
||||
$this->phpci->logFailure('Could not find behat.');
|
||||
|
|
|
@ -69,8 +69,8 @@ class Codeception implements \PHPCI\Plugin
|
|||
return false;
|
||||
}
|
||||
|
||||
$cmd = $codecept . ' run -c "%s"';
|
||||
$success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath . $configPath);
|
||||
$cmd = 'cd "%s" && ' . $codecept . ' run -c "%s"';
|
||||
$success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $this->phpci->buildPath . $configPath);
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
|
|
@ -45,8 +45,11 @@ class Composer implements \PHPCI\Plugin
|
|||
$this->phpci->logFailure('Could not find Composer.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$cmd = $composerLocation . ' --no-ansi --no-interaction ';
|
||||
$cmd = '';
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
$cmd = 'php ';
|
||||
}
|
||||
$cmd .= $composerLocation . ' --no-ansi --no-interaction ';
|
||||
$cmd .= ($this->preferDist ? '--prefer-dist' : null) . ' --working-dir="%s" %s';
|
||||
|
||||
return $this->phpci->executeCommand($cmd, $this->directory, $this->action);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
namespace PHPCI\Plugin;
|
||||
|
||||
use b8\View;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
|
@ -40,13 +41,13 @@ class Email implements \PHPCI\Plugin
|
|||
*/
|
||||
protected $fromAddress;
|
||||
|
||||
public function __construct(Builder $phpci,
|
||||
Build $build,
|
||||
\Swift_Mailer $mailer,
|
||||
array $options = array()
|
||||
public function __construct(
|
||||
Builder $phpci,
|
||||
Build $build,
|
||||
\Swift_Mailer $mailer,
|
||||
array $options = array()
|
||||
|
||||
)
|
||||
{
|
||||
) {
|
||||
$this->phpci = $phpci;
|
||||
$this->build = $build;
|
||||
$this->options = $options;
|
||||
|
@ -84,10 +85,16 @@ class Email implements \PHPCI\Plugin
|
|||
sprintf("Log Output: <br><pre>%s</pre>", $logText)
|
||||
);
|
||||
} else {
|
||||
$view = new View('Email/failed');
|
||||
$view->build = $this->build;
|
||||
$view->project = $this->build->getProject();
|
||||
|
||||
$emailHtml = $view->render();
|
||||
|
||||
$sendFailures = $this->sendSeparateEmails(
|
||||
$addresses,
|
||||
sprintf($subjectTemplate, $projectName, "Failing Build"),
|
||||
sprintf("Log Output: <br><pre>%s</pre>", $logText)
|
||||
$emailHtml
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -99,18 +106,24 @@ class Email implements \PHPCI\Plugin
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array|string $toAddresses Array or single address to send to
|
||||
* @param string $subject Email subject
|
||||
* @param string $body Email body
|
||||
* @param string[]|string $toAddresses Array or single address to send to
|
||||
* @param string[] $ccList
|
||||
* @param string $subject Email subject
|
||||
* @param string $body Email body
|
||||
* @return array Array of failed addresses
|
||||
*/
|
||||
public function sendEmail($toAddresses, $subject, $body)
|
||||
public function sendEmail($toAddresses, $ccList, $subject, $body)
|
||||
{
|
||||
$message = \Swift_Message::newInstance($subject)
|
||||
->setFrom($this->fromAddress)
|
||||
->setTo($toAddresses)
|
||||
->setBody($body)
|
||||
->setContentType("text/html");
|
||||
|
||||
if (is_array($ccList) && count($ccList)) {
|
||||
$message->setCc($ccList);
|
||||
}
|
||||
|
||||
$failedAddresses = array();
|
||||
$this->mailer->send($message, $failedAddresses);
|
||||
|
||||
|
@ -120,8 +133,10 @@ class Email implements \PHPCI\Plugin
|
|||
public function sendSeparateEmails(array $toAddresses, $subject, $body)
|
||||
{
|
||||
$failures = array();
|
||||
$ccList = $this->getCcAddresses();
|
||||
|
||||
foreach ($toAddresses as $address) {
|
||||
$newFailures = $this->sendEmail($address, $subject, $body);
|
||||
$newFailures = $this->sendEmail($address, $ccList, $subject, $body);
|
||||
foreach ($newFailures as $failure) {
|
||||
$failures[] = $failure;
|
||||
}
|
||||
|
@ -150,4 +165,17 @@ class Email implements \PHPCI\Plugin
|
|||
}
|
||||
return $addresses;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCcAddresses()
|
||||
{
|
||||
$ccAddresses = array();
|
||||
|
||||
if (isset($this->options['cc'])) {
|
||||
foreach ($this->options['cc'] as $address) {
|
||||
$ccAddresses[] = $address;
|
||||
}
|
||||
}
|
||||
|
||||
return $ccAddresses;
|
||||
}
|
||||
}
|
||||
|
|
145
PHPCI/Plugin/Util/ComposerPluginInformation.php
Normal file
145
PHPCI/Plugin/Util/ComposerPluginInformation.php
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
|
||||
class ComposerPluginInformation implements InstalledPluginInformation
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $composerPackages;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $pluginInfo = null;
|
||||
|
||||
/**
|
||||
* @param string $filePath The path of installed.json created by composer.
|
||||
* @return ComposerPluginInformation
|
||||
*/
|
||||
public static function buildFromYaml($filePath)
|
||||
{
|
||||
if (file_exists($filePath)) {
|
||||
$installed = json_decode(file_get_contents($filePath));
|
||||
} else {
|
||||
$installed = array();
|
||||
}
|
||||
return new self($installed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass[] $composerPackages This should be the contents of the
|
||||
* installed.json file created by composer
|
||||
*/
|
||||
public function __construct(array $composerPackages)
|
||||
{
|
||||
$this->composerPackages = $composerPackages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of objects. Each one represents an available plugin
|
||||
* and will have the following properties:
|
||||
* name - The friendly name of the plugin (may be an empty string)
|
||||
* class - The class of the plugin (will include namespace)
|
||||
* @return \stdClass[]
|
||||
*/
|
||||
public function getInstalledPlugins()
|
||||
{
|
||||
$this->loadPluginInfo();
|
||||
return $this->pluginInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the class names of plugins that have been
|
||||
* loaded.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPluginClasses()
|
||||
{
|
||||
return array_map(
|
||||
function ($plugin) {
|
||||
return $plugin->class;
|
||||
},
|
||||
$this->getInstalledPlugins()
|
||||
);
|
||||
}
|
||||
|
||||
protected function loadPluginInfo()
|
||||
{
|
||||
if ($this->pluginInfo !== null) {
|
||||
return;
|
||||
}
|
||||
$this->pluginInfo = array();
|
||||
foreach ($this->composerPackages as $package) {
|
||||
$this->addPluginsFromPackage($package);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $package
|
||||
*/
|
||||
protected function addPluginsFromPackage($package)
|
||||
{
|
||||
if (isset($package->extra->phpci)) {
|
||||
$phpciData = $package->extra->phpci;
|
||||
|
||||
if (isset($phpciData->pluginNamespace)) {
|
||||
$rootNamespace = $phpciData->pluginNamespace;
|
||||
} else {
|
||||
$rootNamespace = "";
|
||||
}
|
||||
|
||||
if (is_array($phpciData->suppliedPlugins)) {
|
||||
$this->addPlugins(
|
||||
$phpciData->suppliedPlugins,
|
||||
$package->name,
|
||||
$rootNamespace
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass[] $plugins
|
||||
* @param string $sourcePackageName
|
||||
* @param string $rootNamespace
|
||||
*/
|
||||
protected function addPlugins(
|
||||
array $plugins,
|
||||
$sourcePackageName,
|
||||
$rootNamespace = ""
|
||||
) {
|
||||
foreach ($plugins as $plugin) {
|
||||
if (!isset($plugin->class)) {
|
||||
continue;
|
||||
}
|
||||
$this->addPlugin($plugin, $sourcePackageName, $rootNamespace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $plugin
|
||||
* @param string $sourcePackageName
|
||||
* @param string $rootNamespace
|
||||
*/
|
||||
protected function addPlugin(
|
||||
$plugin,
|
||||
$sourcePackageName,
|
||||
$rootNamespace = ""
|
||||
) {
|
||||
$newPlugin = clone $plugin;
|
||||
|
||||
$newPlugin->class = $rootNamespace . $newPlugin->class;
|
||||
|
||||
if (!isset($newPlugin->name)) {
|
||||
$newPlugin->name = "";
|
||||
}
|
||||
|
||||
$newPlugin->source = $sourcePackageName;
|
||||
|
||||
$this->pluginInfo[] = $newPlugin;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
use PHPCI\BuildLogger;
|
||||
use \PHPCI\Logging\BuildLogger;
|
||||
|
||||
class Executor
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ class Executor
|
|||
*/
|
||||
protected $pluginFactory;
|
||||
|
||||
function __construct(Factory $pluginFactory, BuildLogger $logger)
|
||||
public function __construct(Factory $pluginFactory, BuildLogger $logger)
|
||||
{
|
||||
$this->pluginFactory = $pluginFactory;
|
||||
$this->logger = $logger;
|
||||
|
@ -78,8 +78,7 @@ class Executor
|
|||
$class = str_replace('_', ' ', $plugin);
|
||||
$class = ucwords($class);
|
||||
$class = 'PHPCI\\Plugin\\' . str_replace(' ', '', $class);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$class = $plugin;
|
||||
}
|
||||
|
||||
|
@ -105,4 +104,4 @@ class Executor
|
|||
return $rtn;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,30 +36,10 @@ class Factory {
|
|||
'array'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trys to get a function from the file path specified. If the
|
||||
* file returns a function then $this will be passed to it.
|
||||
* This enables the config file to call any public methods.
|
||||
*
|
||||
* @param $configPath
|
||||
* @return bool - true if the function exists else false.
|
||||
*/
|
||||
public function addConfigFromFile($configPath)
|
||||
public function getLastOptions()
|
||||
{
|
||||
// The file is expected to return a function which can
|
||||
// act on the pluginFactory to register any resources needed.
|
||||
if (file_exists($configPath)) {
|
||||
$configFunction = require($configPath);
|
||||
if (is_callable($configFunction)) {
|
||||
$configFunction($this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getLastOptions() {
|
||||
return $this->currentPluginOptions;
|
||||
}
|
||||
|
||||
|
|
104
PHPCI/Plugin/Util/FilesPluginInformation.php
Normal file
104
PHPCI/Plugin/Util/FilesPluginInformation.php
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
class FilesPluginInformation implements InstalledPluginInformation
|
||||
{
|
||||
|
||||
/**
|
||||
* A collection of all the file path information for
|
||||
* the installed plugins.
|
||||
*
|
||||
* @var \SplFileInfo[]
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* Each item in the array contains the information for
|
||||
* a single plugin.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pluginInfo = null;
|
||||
|
||||
public static function newFromDir($dirPath)
|
||||
{
|
||||
return new self(new \DirectoryIterator($dirPath));
|
||||
}
|
||||
|
||||
public function __construct(\Iterator $files)
|
||||
{
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of objects. Each one represents an available plugin
|
||||
* and will have the following properties:
|
||||
* name - The friendly name of the plugin (may be an empty string)
|
||||
* class - The class of the plugin (will include namespace)
|
||||
* @return \stdClass[]
|
||||
*/
|
||||
public function getInstalledPlugins()
|
||||
{
|
||||
if ($this->pluginInfo === null) {
|
||||
$this->loadPluginInfo();
|
||||
}
|
||||
return $this->pluginInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the class names of plugins that have been
|
||||
* loaded.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPluginClasses()
|
||||
{
|
||||
return array_map(
|
||||
function ($plugin) {
|
||||
return $plugin->class;
|
||||
},
|
||||
$this->getInstalledPlugins()
|
||||
);
|
||||
}
|
||||
|
||||
protected function loadPluginInfo()
|
||||
{
|
||||
$this->pluginInfo = array();
|
||||
foreach ($this->files as $fileInfo) {
|
||||
if ($fileInfo instanceof \SplFileInfo) {
|
||||
if ($fileInfo->isFile()) {
|
||||
$this->addPluginFromFile($fileInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function addPluginFromFile(\SplFileInfo $fileInfo)
|
||||
{
|
||||
$newPlugin = new \stdClass();
|
||||
$newPlugin->class = $this->getFullClassFromFile($fileInfo);
|
||||
$newPlugin->source = "core";
|
||||
$parts = explode('\\', $newPlugin->class);
|
||||
$newPlugin->name = end($parts);
|
||||
|
||||
$this->pluginInfo[] = $newPlugin;
|
||||
}
|
||||
|
||||
protected function getFullClassFromFile(\SplFileInfo $fileInfo)
|
||||
{
|
||||
//TODO: Something less horrible than a regular expression
|
||||
// on the contents of a file
|
||||
$contents = file_get_contents($fileInfo->getRealPath());
|
||||
|
||||
$matches = array();
|
||||
preg_match('#class +([A-Za-z]+) +implements#i', $contents, $matches);
|
||||
$className = $matches[1];
|
||||
|
||||
$matches = array();
|
||||
preg_match('#namespace +([A-Za-z\\\\]+);#i', $contents, $matches);
|
||||
$namespace = $matches[1];
|
||||
|
||||
return $namespace . '\\' . $className;
|
||||
}
|
||||
}
|
23
PHPCI/Plugin/Util/InstalledPluginInformation.php
Normal file
23
PHPCI/Plugin/Util/InstalledPluginInformation.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
|
||||
interface InstalledPluginInformation
|
||||
{
|
||||
/**
|
||||
* Returns an array of objects. Each one represents an available plugin
|
||||
* and will have the following properties:
|
||||
* name - The friendly name of the plugin (may be an empty string)
|
||||
* class - The class of the plugin (will include namespace)
|
||||
* @return \stdClass[]
|
||||
*/
|
||||
public function getInstalledPlugins();
|
||||
|
||||
/**
|
||||
* Returns an array of all the class names of plugins that have been
|
||||
* loaded.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPluginClasses();
|
||||
}
|
48
PHPCI/Plugin/Util/PluginInformationCollection.php
Normal file
48
PHPCI/Plugin/Util/PluginInformationCollection.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
class PluginInformationCollection implements InstalledPluginInformation
|
||||
{
|
||||
/**
|
||||
* @var InstalledPluginInformation[]
|
||||
*/
|
||||
protected $pluginInformations = array();
|
||||
|
||||
public function add(InstalledPluginInformation $information)
|
||||
{
|
||||
$this->pluginInformations[] = $information;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of objects. Each one represents an available plugin
|
||||
* and will have the following properties:
|
||||
* name - The friendly name of the plugin (may be an empty string)
|
||||
* class - The class of the plugin (will include namespace)
|
||||
* @return \stdClass[]
|
||||
*/
|
||||
public function getInstalledPlugins()
|
||||
{
|
||||
$arr = array();
|
||||
foreach ($this->pluginInformations as $single) {
|
||||
$arr = array_merge($arr, $single->getInstalledPlugins());
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the class names of plugins that have been
|
||||
* loaded.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPluginClasses()
|
||||
{
|
||||
$arr = array();
|
||||
foreach ($this->pluginInformations as $single) {
|
||||
$arr = array_merge($arr, $single->getPluginClasses());
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
}
|
7
PHPCI/Store.php
Normal file
7
PHPCI/Store.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
namespace PHPCI;
|
||||
|
||||
abstract class Store extends \b8\Store
|
||||
{
|
||||
|
||||
}
|
|
@ -8,7 +8,7 @@ namespace PHPCI\Store\Base;
|
|||
|
||||
use b8\Database;
|
||||
use b8\Exception\HttpException;
|
||||
use b8\Store;
|
||||
use PHPCI\Store;
|
||||
use PHPCI\Model\BuildMeta;
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,7 @@ class BuildMetaStoreBase extends Store
|
|||
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM build_meta WHERE id = :id LIMIT 1';
|
||||
$query = 'SELECT * FROM `build_meta` WHERE `id` = :id LIMIT 1';
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':id', $value);
|
||||
|
||||
|
@ -58,7 +58,7 @@ class BuildMetaStoreBase extends Store
|
|||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM build_meta WHERE build_id = :build_id' . $add;
|
||||
$query = 'SELECT * FROM `build_meta` WHERE `build_id` = :build_id' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':build_id', $value);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace PHPCI\Store\Base;
|
|||
|
||||
use b8\Database;
|
||||
use b8\Exception\HttpException;
|
||||
use b8\Store;
|
||||
use PHPCI\Store;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,7 @@ class BuildStoreBase extends Store
|
|||
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM build WHERE id = :id LIMIT 1';
|
||||
$query = 'SELECT * FROM `build` WHERE `id` = :id LIMIT 1';
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':id', $value);
|
||||
|
||||
|
@ -58,7 +58,7 @@ class BuildStoreBase extends Store
|
|||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM build WHERE project_id = :project_id' . $add;
|
||||
$query = 'SELECT * FROM `build` WHERE `project_id` = :project_id' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':project_id', $value);
|
||||
|
||||
|
@ -90,7 +90,7 @@ class BuildStoreBase extends Store
|
|||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM build WHERE status = :status' . $add;
|
||||
$query = 'SELECT * FROM `build` WHERE `status` = :status' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':status', $value);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace PHPCI\Store\Base;
|
|||
|
||||
use b8\Database;
|
||||
use b8\Exception\HttpException;
|
||||
use b8\Store;
|
||||
use PHPCI\Store;
|
||||
use PHPCI\Model\Project;
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,7 @@ class ProjectStoreBase extends Store
|
|||
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM project WHERE id = :id LIMIT 1';
|
||||
$query = 'SELECT * FROM `project` WHERE `id` = :id LIMIT 1';
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':id', $value);
|
||||
|
||||
|
@ -58,7 +58,7 @@ class ProjectStoreBase extends Store
|
|||
|
||||
$count = null;
|
||||
|
||||
$query = 'SELECT * FROM project WHERE title = :title' . $add;
|
||||
$query = 'SELECT * FROM `project` WHERE `title` = :title' . $add;
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':title', $value);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace PHPCI\Store\Base;
|
|||
|
||||
use b8\Database;
|
||||
use b8\Exception\HttpException;
|
||||
use b8\Store;
|
||||
use PHPCI\Store;
|
||||
use PHPCI\Model\User;
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,7 @@ class UserStoreBase extends Store
|
|||
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM user WHERE id = :id LIMIT 1';
|
||||
$query = 'SELECT * FROM `user` WHERE `id` = :id LIMIT 1';
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':id', $value);
|
||||
|
||||
|
@ -50,7 +50,7 @@ class UserStoreBase extends Store
|
|||
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM user WHERE email = :email LIMIT 1';
|
||||
$query = 'SELECT * FROM `user` WHERE `email` = :email LIMIT 1';
|
||||
$stmt = Database::getConnection($useConnection)->prepare($query);
|
||||
$stmt->bindValue(':email', $value);
|
||||
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
<div id="title">
|
||||
<h1 style="display: inline-block">Build #<?php print $build->getId(); ?></h1>
|
||||
<h3 style="margin-left: 40px; display: inline-block">Branch: <?php print $build->getBranch(); ?> - <?php print $build->getCommitId() == 'Manual' ? 'Manual Build' : 'Commit: ' . $build->getCommitId(); ?></h3>
|
||||
<h1 style="display: inline-block"><?php print $build->getProject()->getTitle(); ?> - Build #<?php print $build->getId(); ?></h1>
|
||||
|
||||
<div id="build-info">
|
||||
<strong>Branch: </strong> <?php print $build->getBranch(); ?><br>
|
||||
<strong>Committer: </strong> <?php print $build->getCommitterEmail(); ?><br>
|
||||
<strong>Commit ID: </strong> <?php print $build->getCommitId() == 'Manual' ? 'HEAD' : $build->getCommitId(); ?><br>
|
||||
<strong>Commit Message: </strong> <?php print $build->getCommitMessage(); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li><a href="<?= PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
|
||||
<li><a href="<?= PHPCI_URL ?>project/view/<?php print $build->getProject()->getId(); ?>"><i class="icon-folder-open"></i> <?php print htmlspecialchars($build->getProject()->getTitle()); ?></a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>project/view/<?php print $build->getProject()->getId(); ?>"><i class="icon-folder-open"></i> <?php print htmlspecialchars($build->getProject()->getTitle()); ?></a></li>
|
||||
</ul>
|
||||
<h5>Options</h5>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li><a href="<?= PHPCI_URL ?>build/rebuild/<?php print $build->getId(); ?>"><i class="icon-cog"></i> Rebuild</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>build/rebuild/<?php print $build->getId(); ?>"><i class="icon-cog"></i> Rebuild</a></li>
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<li><a href="#" id="delete-build"><i class="icon-trash"></i> Delete Build</a></li>
|
||||
<?php endif; ?>
|
||||
|
@ -39,4 +45,4 @@ foreach ($plugins as $plugin) {
|
|||
$(document).ready(function() {
|
||||
PHPCI.renderPlugins();
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -37,8 +37,8 @@ switch($build->getStatus())
|
|||
}
|
||||
?>
|
||||
<tr class="<?php print $cls; ?>">
|
||||
<td><a href="<?= PHPCI_URL ?>build/view/<?php print $build->getId(); ?>">#<?php print str_pad($build->getId(), 6, '0', STR_PAD_LEFT); ?></a></td>
|
||||
<td><a href="<?= PHPCI_URL ?>project/view/<?php print $build->getProjectId(); ?>">
|
||||
<td><a href="<?php echo PHPCI_URL ?>build/view/<?php print $build->getId(); ?>">#<?php print str_pad($build->getId(), 6, '0', STR_PAD_LEFT); ?></a></td>
|
||||
<td><a href="<?php echo PHPCI_URL ?>project/view/<?php print $build->getProjectId(); ?>">
|
||||
<?php
|
||||
if (is_object($build->getProject())) {
|
||||
print htmlspecialchars($build->getProject()->getTitle());
|
||||
|
@ -56,24 +56,24 @@ switch($build->getStatus())
|
|||
$plugins = array();
|
||||
}
|
||||
if ( 0 === count($plugins) ) {
|
||||
?> <span class='label label-<?= $subcls ?>'><?= $status ?></span> <?php
|
||||
?> <span class='label label-<?php echo $subcls ?>'><?php echo $status ?></span> <?php
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
foreach($plugins as $plugin => $pluginstatus):
|
||||
$subcls = $pluginstatus?'label label-success':'label label-danger';
|
||||
?> <span class='<?= $subcls ?>'><?php print $this->Build()->formatPluginName($plugin); ?></span> <?php endforeach; ?>
|
||||
?> <span class='<?php echo $subcls ?>'><?php print $this->Build()->formatPluginName($plugin); ?></span> <?php endforeach; ?>
|
||||
<br style='clear:both;' />
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default btn-small" href="<?= PHPCI_URL ?>build/view/<?php print $build->getId(); ?>">View</a>
|
||||
<a class="btn btn-default btn-small" href="<?php echo PHPCI_URL ?>build/view/<?php print $build->getId(); ?>">View</a>
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<button class="btn btn-default btn-small dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="javascript:confirmDelete('<?= PHPCI_URL ?>build/delete/<?php print $build->getId(); ?>', 'Build').onClose = function(){refreshBuildsTable();};">Delete Build</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>build/delete/<?php print $build->getId(); ?>" class="phpci-app-delete-build">Delete Build</a></li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
|
15
PHPCI/View/Email/failed.phtml
Normal file
15
PHPCI/View/Email/failed.phtml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<div style="background: #900; padding: 25px;">
|
||||
<div style="background: #fff; padding: 15px; border-radius: 5px">
|
||||
<div style="font-family: arial, verdana, sans-serif; font-size: 25px; margin-bottom: 15px">
|
||||
<?= $project->getTitle(); ?> - Build #<?= $build->getId(); ?>
|
||||
</div>
|
||||
|
||||
<div style="font-family: arial, verdana, sans-serif; font-size: 15px">
|
||||
<p>Your commit <strong><?= $build->getCommitId(); ?></strong> caused a failed build in project <strong><?= $project->getTitle(); ?></strong>.</p>
|
||||
|
||||
<p style="margin: 10px; background: #fafafa"><?= $build->getCommitMessage(); ?></p>
|
||||
|
||||
<p>Please review <a href="<?= $build->getCommitLink(); ?>">your commit</a> and the <a href="<?= PHPCI_URL . 'build/view/' . $build->getId(); ?>">build log</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -4,14 +4,14 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li class="active"><a href="<?= PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
|
||||
<li class="active"><a href="<?php echo PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
|
||||
</ul>
|
||||
|
||||
<?php if (count($projects)): ?>
|
||||
<h5>Projects</h5>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<?php foreach($projects as $project): ?>
|
||||
<li><a href="<?= PHPCI_URL ?>project/view/<?php print $project->getId(); ?>"><?php print htmlspecialchars($project->getTitle()); ?></a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>project/view/<?php print $project->getId(); ?>"><?php print htmlspecialchars($project->getTitle()); ?></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
@ -60,8 +60,10 @@
|
|||
<script>
|
||||
refreshBuildsTable = function()
|
||||
{
|
||||
$('#latest-builds').load('<?= PHPCI_URL ?>home/latest');
|
||||
$('#latest-builds').load('<?php echo PHPCI_URL ?>home/latest', function () {
|
||||
$('#latest-builds').trigger('latest-builds:reload');
|
||||
});
|
||||
};
|
||||
|
||||
setInterval(refreshBuildsTable, 10000);
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<h1 id="title">Plugins</h1>
|
||||
<h1 id="title">Packages and Provided Plugins</h1>
|
||||
<?php if (!$canInstall): ?>
|
||||
<p class="alert alert-danger">PHPCI cannot automatically install/remove plugins for you, as either the <strong>shell_exec()</strong>
|
||||
function is disabled or PHPCI could not find Composer. PHPCI will update composer.json for you, but you will need to run Composer manually to make the changes.</p>
|
||||
|
@ -9,19 +9,42 @@
|
|||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_GET['r'])): ?>
|
||||
<p class="alert alert-success"><strong><?= $_GET['r']; ?></strong> has been removed.</p>
|
||||
<p class="alert alert-success"><strong><?php echo $_GET['r']; ?></strong> has been removed.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_GET['i'])): ?>
|
||||
<p class="alert alert-success"><strong><?= $_GET['i']; ?></strong> has been installed.</p>
|
||||
<p class="alert alert-success"><strong><?php echo $_GET['i']; ?></strong> has been installed.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_GET['w'])): ?>
|
||||
<p class="alert alert-success"><strong><?= $_GET['w']; ?></strong> has been added to composer.json and will be installed next time you run composer update.</p>
|
||||
<p class="alert alert-success"><strong><?php echo $_GET['w']; ?></strong> has been added to composer.json and will be installed next time you run composer update.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title">Installed Plugins</h3>
|
||||
<h3 class="title">Available Plugins</h3>
|
||||
|
||||
<table class="table-striped table-bordered table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Class</th>
|
||||
<th>Provided by Package</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($plugins as $plugin): ?>
|
||||
<tr>
|
||||
<td><?= $plugin->name; ?></td>
|
||||
<td><?= $plugin->class; ?></td>
|
||||
<td><?= $plugin->source; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title">Installed Packages</h3>
|
||||
|
||||
<table class="table-striped table-bordered table">
|
||||
<thead>
|
||||
|
@ -32,13 +55,13 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($installed as $package => $version): ?>
|
||||
<?php foreach ($installedPackages as $package => $version): ?>
|
||||
<tr>
|
||||
<td><?= $package; ?></td>
|
||||
<td><?= $version; ?></td>
|
||||
<td><?php echo $package; ?></td>
|
||||
<td><?php echo $version; ?></td>
|
||||
<td>
|
||||
<?php if (!in_array($package, $required) && $canWrite): ?>
|
||||
<a class="btn btn-danger btn-small" href="<?= PHPCI_URL ?>plugin/remove?package=<?= $package; ?>">Remove »</a>
|
||||
<a class="btn btn-danger btn-small" href="<?php echo PHPCI_URL ?>plugin/remove?package=<?php echo $package; ?>">Remove »</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -48,7 +71,7 @@
|
|||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title">Suggested Plugins</h3>
|
||||
<h3 class="title">Suggested Packages</h3>
|
||||
|
||||
<table class="table-striped table-bordered table">
|
||||
<thead>
|
||||
|
@ -59,14 +82,14 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($suggested as $package => $version): ?>
|
||||
<?php if (in_array($package, array_keys($installed))) { continue; } ?>
|
||||
<?php foreach ($suggestedPackages as $package => $version): ?>
|
||||
<?php if (in_array($package, array_keys($installedPackages))) { continue; } ?>
|
||||
<tr>
|
||||
<td><?= $package; ?></td>
|
||||
<td><?= $version; ?></td>
|
||||
<td><?php echo $package; ?></td>
|
||||
<td><?php echo $version; ?></td>
|
||||
<td>
|
||||
<?php if ($canWrite): ?>
|
||||
<button data-name="<?= $package; ?>" class="install-package btn btn-success btn-small">Install »</button>
|
||||
<button data-name="<?php echo $package; ?>" class="install-package btn btn-success btn-small">Install »</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -76,7 +99,7 @@
|
|||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h3 class="title">Search Packagist for More Plugins</h3>
|
||||
<h3 class="title">Search Packagist for More Packages</h3>
|
||||
|
||||
<div class="input-group">
|
||||
<input id="search-query" type="text" class="form-control">
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li><a href="<?= PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
|
||||
<li><a href="<?= PHPCI_URL ?>project/view/<?php print $project->getId(); ?>"><i class="icon-folder-open"></i> <?php print htmlspecialchars($project->getTitle()); ?></a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>project/view/<?php print $project->getId(); ?>"><i class="icon-folder-open"></i> <?php print htmlspecialchars($project->getTitle()); ?></a></li>
|
||||
</ul>
|
||||
<h5>Options</h5>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li><a href="<?= PHPCI_URL ?>project/build/<?php print $project->getId(); ?>"><i class="icon-cog"></i> Build Now</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>project/build/<?php print $project->getId(); ?>"><i class="icon-cog"></i> Build Now</a></li>
|
||||
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<li><a href="<?= PHPCI_URL ?>project/edit/<?php print $project->getId(); ?>"><i class="icon-edit"></i> Edit Project</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>project/edit/<?php print $project->getId(); ?>"><i class="icon-edit"></i> Edit Project</a></li>
|
||||
<li><a href="#" id="delete-project"><i class="icon-trash"></i> Delete Project</a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
|
@ -27,17 +27,17 @@
|
|||
switch($project->getType())
|
||||
{
|
||||
case 'github':
|
||||
$url = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . '://' . $_SERVER['HTTP_HOST'] . '/github/webhook/' . $project->getId();
|
||||
$url = PHPCI_URL . 'webhook/github/' . $project->getId();
|
||||
print ' as a "WebHook URL" in the <a href="https://github.com/' . $project->getReference() . '/settings/hooks">Service Hooks</a> section of your Github repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
|
||||
case 'gitlab':
|
||||
$url = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . '://' . $_SERVER['HTTP_HOST'] . '/gitlab/webhook/' . $project->getId();
|
||||
$url = PHPCI_URL. 'webhook/gitlab/' . $project->getId();
|
||||
print ' as a "WebHook URL" in the Web Hooks section of your Gitlab repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
|
||||
case 'bitbucket':
|
||||
$url = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . '://' . $_SERVER['HTTP_HOST'] . '/bitbucket/webhook/' . $project->getId();
|
||||
$url = PHPCI_URL . 'webhook/bitbucket/' . $project->getId();
|
||||
print ' as a "POST" service in the <a href="https://bitbucket.org/' . $project->getReference() . '/admin/services">Services</a> section of your Bitbucket repository.<br><br><strong style="word-wrap: break-word;">' . $url . '</strong>';
|
||||
break;
|
||||
}
|
||||
|
@ -86,14 +86,14 @@
|
|||
<script>
|
||||
setInterval(function()
|
||||
{
|
||||
$('#latest-builds').load('<?= PHPCI_URL ?>project/builds/<?php print $project->getId(); ?>');
|
||||
$('#latest-builds').load('<?php echo PHPCI_URL ?>project/builds/<?php print $project->getId(); ?>');
|
||||
}, 10000);
|
||||
|
||||
$(function() {
|
||||
$('#delete-project').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
confirmDelete(
|
||||
"<?= PHPCI_URL ?>project/delete/<?php print $project->getId(); ?>", "Project"
|
||||
"<?php echo PHPCI_URL ?>project/delete/<?php print $project->getId(); ?>", "Project"
|
||||
).onCloseConfirmed = function () {window.location = '/'};
|
||||
});
|
||||
})
|
||||
|
|
|
@ -39,4 +39,4 @@ if(!empty($token)) {
|
|||
?>
|
||||
|
||||
$(document).ready(setupProjectForm);
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="<?= PHPCI_URL ?>assets/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/bootstrap.min.css">
|
||||
<script src="//code.jquery.com/jquery-1.8.1.min.js"></script>
|
||||
<script src="<?= PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
|
@ -88,4 +88,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
?>
|
||||
<?php if (!empty($id) && empty($settings['phpci']['github']['token'])): ?>
|
||||
<p class="alert alert-warning clearfix">
|
||||
Before you can start using Github, you need to <a href="<?= $githubUri; ?>">sign in</a> and grant PHPCI access to your account.
|
||||
Before you can start using Github, you need to <a href="<?php echo $githubUri; ?>">sign in</a> and grant PHPCI access to your account.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
|||
<p class="alert alert-success">
|
||||
PHPCI is successfully linked to Github account
|
||||
<strong>
|
||||
<a href="<?= $githubUser['html_url']; ?>"><?= $githubUser['name']; ?></a>
|
||||
<a href="<?php echo $githubUser['html_url']; ?>"><?php echo $githubUser['name']; ?></a>
|
||||
</strong>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
|
|
@ -78,11 +78,11 @@ foreach($projects as $project):
|
|||
?>
|
||||
<tr class="<?php print $cls; ?>">
|
||||
<td>
|
||||
<span class='label label-<?= $subcls ?>'>
|
||||
<?= $health ?>
|
||||
<span class='label label-<?php echo $subcls ?>'>
|
||||
<?php echo $health ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><a href='<?= PHPCI_URL ?>project/view/<?= $project->getId() ?>'><?= htmlspecialchars($project->getTitle()) ?></a></td>
|
||||
<td><a href='<?php echo PHPCI_URL ?>project/view/<?php echo $project->getId() ?>'><?php echo htmlspecialchars($project->getTitle()) ?></a></td>
|
||||
<td><?php print is_null($success) ? 'Never' : $success; ?></td>
|
||||
<td><?php print is_null($failure) ? 'Never' : $failure; ?></td>
|
||||
<td>
|
||||
|
@ -92,6 +92,6 @@ foreach($projects as $project):
|
|||
}
|
||||
?>
|
||||
</td>
|
||||
<td><a class="btn btn-default btn-small" href='<?= PHPCI_URL ?>project/build/<?= $project->getId(); ?>'>build now »</a></td>
|
||||
<td><a class="btn btn-default btn-small" href='<?php echo PHPCI_URL ?>project/build/<?php echo $project->getId(); ?>'>build now »</a></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li><a href="<?= PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
|
||||
<li class="active"><a href="<?= PHPCI_URL ?>user"><i class="icon-user"></i> Users</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
|
||||
<li class="active"><a href="<?php echo PHPCI_URL ?>user"><i class="icon-user"></i> Users</a></li>
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<li><a href="<?= PHPCI_URL ?>user/add"><i class="icon-plus-sign"></i> Add User</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>user/add"><i class="icon-plus-sign"></i> Add User</a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -39,18 +39,18 @@
|
|||
}
|
||||
?>
|
||||
<tr class="<?php print $cls; ?>">
|
||||
<td><a href="<?= PHPCI_URL ?>user/edit/<?php print $user->getId(); ?>"><?php print $user->getEmail(); ?></a></td>
|
||||
<td><a href="<?php echo PHPCI_URL ?>user/edit/<?php print $user->getId(); ?>"><?php print $user->getEmail(); ?></a></td>
|
||||
<td><?php print htmlspecialchars($user->getName()); ?></td>
|
||||
<td><?php print $status; ?></td>
|
||||
<td>
|
||||
<?php if($this->User()->getIsAdmin()): ?>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default btn-small" href="<?= PHPCI_URL ?>user/edit/<?php print $user->getId(); ?>">Edit</a>
|
||||
<a class="btn btn-default btn-small" href="<?php echo PHPCI_URL ?>user/edit/<?php print $user->getId(); ?>">Edit</a>
|
||||
<button class="btn btn-default btn-small dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="javascript:confirmDelete('<?= PHPCI_URL ?>user/delete/<?php print $user->getId(); ?>', 'User', true);">Delete User</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>user/delete/<?php print $user->getId(); ?>" class="phpci-app-delete-user">Delete User</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
<?php print $form; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,21 +7,22 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link href='//fonts.googleapis.com/css?family=Roboto:300,500&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" type="text/css" href="<?= PHPCI_URL ?>assets/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="<?= PHPCI_URL ?>assets/css/phpci.css">
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo PHPCI_URL ?>assets/css/phpci.css">
|
||||
|
||||
<link rel="shortcut icon" type="image/x-icon" href="<?= PHPCI_URL ?>favicon.ico">
|
||||
<link rel="shortcut icon" type="image/png" href="<?= PHPCI_URL ?>assets/img/favicon.png">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="<?php echo PHPCI_URL ?>favicon.ico">
|
||||
<link rel="shortcut icon" type="image/png" href="<?php echo PHPCI_URL ?>assets/img/favicon.png">
|
||||
|
||||
<script>window.PHPCI_URL = <?php print json_encode(PHPCI_URL) ?></script>
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||
|
||||
<script src="<?= PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
|
||||
<script src="<?= PHPCI_URL ?>assets/js/jqueryui.js"></script>
|
||||
<script src="<?= PHPCI_URL ?>assets/js/class.js"></script>
|
||||
<script src="<?= PHPCI_URL ?>assets/js/phpci.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/bootstrap.min.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/jqueryui.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/class.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/phpci.js"></script>
|
||||
<script src="<?php echo PHPCI_URL ?>assets/js/init.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
|
@ -32,7 +33,7 @@
|
|||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
|
||||
<a class="navbar-brand" href="<?= PHPCI_URL ?>"><img src="<?= PHPCI_URL ?>/assets/img/logo.png"></a>
|
||||
<a class="navbar-brand" href="<?php echo PHPCI_URL ?>"><img src="<?php echo PHPCI_URL ?>/assets/img/logo.png"></a>
|
||||
|
||||
<div class="nav-collapse collapse navbar-responsive-collapse">
|
||||
<ul class="nav navbar-nav pull-right">
|
||||
|
@ -41,15 +42,15 @@
|
|||
<?php if ($this->User()->getIsAdmin()): ?>
|
||||
<li>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-success navbar-btn" href="<?= PHPCI_URL ?>project/add">Add Project</a>
|
||||
<a class="btn btn-success navbar-btn" href="<?php echo PHPCI_URL ?>project/add">Add Project</a>
|
||||
|
||||
<button type="button" class="btn navbar-btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
Admin <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="/settings">Settings</a></li>
|
||||
<li><a href="/plugin">Manage Plugins</a></li>
|
||||
<li><a href="/user">Manage Users</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>settings">Settings</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>plugin">Manage Plugins</a></li>
|
||||
<li><a href="<?php echo PHPCI_URL ?>user">Manage Users</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
|
|
49
Tests/PHPCI/Helper/BuildInterpolatorTest.php
Normal file
49
Tests/PHPCI/Helper/BuildInterpolatorTest.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Tests\Helper;
|
||||
|
||||
use PHPCI\Helper\BuildInterpolator;
|
||||
use Prophecy\PhpUnit\ProphecyTestCase;
|
||||
|
||||
class BuildInterpolatorTest extends ProphecyTestCase
|
||||
{
|
||||
/**
|
||||
* @var BuildInterpolator
|
||||
*/
|
||||
protected $testedInterpolator;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setup();
|
||||
$this->testedInterpolator = new BuildInterpolator();
|
||||
}
|
||||
|
||||
public function testInterpolate_LeavesStringsUnchangedByDefault()
|
||||
{
|
||||
$string = "Hello World";
|
||||
$expectedOutput = "Hello World";
|
||||
|
||||
$actualOutput = $this->testedInterpolator->interpolate($string);
|
||||
|
||||
$this->assertEquals($expectedOutput, $actualOutput);
|
||||
}
|
||||
|
||||
public function testInterpolate_LeavesStringsUnchangedWhenBuildIsSet()
|
||||
{
|
||||
$build = $this->prophesize('PHPCI\\Model\\Build')->reveal();
|
||||
|
||||
$string = "Hello World";
|
||||
$expectedOutput = "Hello World";
|
||||
|
||||
$this->testedInterpolator->setupInterpolationVars(
|
||||
$build,
|
||||
"/buildpath/",
|
||||
"phpci.com"
|
||||
);
|
||||
|
||||
$actualOutput = $this->testedInterpolator->interpolate($string);
|
||||
|
||||
$this->assertEquals($expectedOutput, $actualOutput);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ class CommandExecutorTest extends ProphecyTestCase
|
|||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$mockBuildLogger = $this->prophesize('\PHPCI\BuildLogger');
|
||||
$mockBuildLogger = $this->prophesize('PHPCI\Logging\BuildLogger');
|
||||
$this->testedExecutor = new CommandExecutor($mockBuildLogger->reveal(), __DIR__ . "/");
|
||||
}
|
||||
|
||||
|
|
107
Tests/PHPCI/Logging/BuildLoggerTest.php
Normal file
107
Tests/PHPCI/Logging/BuildLoggerTest.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Tests\Helper;
|
||||
|
||||
use PHPCI\Logging\BuildLogger;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTestCase;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class BuildLoggerTest extends ProphecyTestCase
|
||||
{
|
||||
/**
|
||||
* @var BuildLogger
|
||||
*/
|
||||
protected $testedBuildLogger;
|
||||
|
||||
protected $mockLogger;
|
||||
|
||||
protected $mockBuild;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->mockLogger = $this->prophesize('\Psr\Log\LoggerInterface');
|
||||
$this->mockBuild = $this->prophesize('\PHPCI\Model\Build');
|
||||
|
||||
$this->testedBuildLogger = new BuildLogger(
|
||||
$this->mockLogger->reveal(),
|
||||
$this->mockBuild->reveal()
|
||||
);
|
||||
}
|
||||
|
||||
public function testLog_CallsWrappedLogger()
|
||||
{
|
||||
$level = LogLevel::NOTICE;
|
||||
$message = "Testing";
|
||||
$contextIn = array();
|
||||
|
||||
$this->mockLogger->log($level, $message, Argument::type('array'))
|
||||
->shouldBeCalledTimes(1);
|
||||
|
||||
$this->testedBuildLogger->log($message, $level, $contextIn);
|
||||
}
|
||||
|
||||
public function testLog_CallsWrappedLoggerForEachMessage()
|
||||
{
|
||||
$level = LogLevel::NOTICE;
|
||||
$message = array("One", "Two", "Three");
|
||||
$contextIn = array();
|
||||
|
||||
$this->mockLogger->log($level, "One", Argument::type('array'))
|
||||
->shouldBeCalledTimes(1);
|
||||
|
||||
$this->mockLogger->log($level, "Two", Argument::type('array'))
|
||||
->shouldBeCalledTimes(1);
|
||||
|
||||
$this->mockLogger->log($level, "Three", Argument::type('array'))
|
||||
->shouldBeCalledTimes(1);
|
||||
|
||||
$this->testedBuildLogger->log($message, $level, $contextIn);
|
||||
}
|
||||
|
||||
public function testLog_AddsBuildToContext()
|
||||
{
|
||||
$level = LogLevel::NOTICE;
|
||||
$message = "Testing";
|
||||
$contextIn = array();
|
||||
|
||||
$expectedContext = array(
|
||||
'build' => $this->mockBuild->reveal()
|
||||
);
|
||||
|
||||
$this->mockLogger->log($level, $message, $expectedContext)
|
||||
->shouldBeCalledTimes(1);
|
||||
|
||||
$this->testedBuildLogger->log($message, $level, $contextIn);
|
||||
}
|
||||
|
||||
public function testLogFailure_LogsAsErrorLevel()
|
||||
{
|
||||
$message = "Testing";
|
||||
$expectedLevel = LogLevel::ERROR;
|
||||
|
||||
$this->mockLogger->log($expectedLevel,
|
||||
Argument::type('string'),
|
||||
Argument::type('array'))
|
||||
->shouldBeCalledTimes(1);
|
||||
|
||||
$this->testedBuildLogger->logFailure($message);
|
||||
}
|
||||
|
||||
public function testLogFailure_AddsExceptionContext()
|
||||
{
|
||||
$message = "Testing";
|
||||
|
||||
$exception = new \Exception("Expected Exception");
|
||||
|
||||
|
||||
$this->mockLogger->log(Argument::type('string'),
|
||||
Argument::type('string'),
|
||||
Argument::withEntry('exception', $exception))
|
||||
->shouldBeCalledTimes(1);
|
||||
|
||||
$this->testedBuildLogger->logFailure($message, $exception);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
<?php
|
||||
|
||||
use \PHPCI\Helper\LoggerConfig;
|
||||
namespace PHPCI\Plugin\Tests\Helper;
|
||||
|
||||
class LoggerConfigTest extends PHPUnit_Framework_TestCase
|
||||
use \PHPCI\Logging\LoggerConfig;
|
||||
|
||||
class LoggerConfigTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGetFor_ReturnsPSRLogger()
|
||||
{
|
||||
|
@ -20,9 +22,9 @@ class LoggerConfigTest extends PHPUnit_Framework_TestCase
|
|||
|
||||
public function testGetFor_AttachesAlwaysPresentHandlers()
|
||||
{
|
||||
$expectedHandler = new Monolog\Handler\NullHandler();
|
||||
$expectedHandler = new \Monolog\Handler\NullHandler();
|
||||
$config = new LoggerConfig(array(
|
||||
LoggerConfig::KEY_AlwaysLoaded => function() use ($expectedHandler) {
|
||||
LoggerConfig::KEY_ALWAYS_LOADED => function() use ($expectedHandler) {
|
||||
return array($expectedHandler);
|
||||
}
|
||||
));
|
||||
|
@ -36,7 +38,7 @@ class LoggerConfigTest extends PHPUnit_Framework_TestCase
|
|||
|
||||
public function testGetFor_AttachesSpecificHandlers()
|
||||
{
|
||||
$expectedHandler = new Monolog\Handler\NullHandler();
|
||||
$expectedHandler = new \Monolog\Handler\NullHandler();
|
||||
$config = new LoggerConfig(array(
|
||||
"Specific" => function() use ($expectedHandler) {
|
||||
return array($expectedHandler);
|
||||
|
@ -52,8 +54,8 @@ class LoggerConfigTest extends PHPUnit_Framework_TestCase
|
|||
|
||||
public function testGetFor_IgnoresAlternativeHandlers()
|
||||
{
|
||||
$expectedHandler = new Monolog\Handler\NullHandler();
|
||||
$alternativeHandler = new Monolog\Handler\NullHandler();
|
||||
$expectedHandler = new \Monolog\Handler\NullHandler();
|
||||
$alternativeHandler = new \Monolog\Handler\NullHandler();
|
||||
|
||||
$config = new LoggerConfig(array(
|
||||
"Specific" => function() use ($expectedHandler) {
|
|
@ -162,7 +162,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
$this->mockMailer->expects($this->once())
|
||||
->method('send');
|
||||
$this->testedEmailPlugin->sendEmail("test@email.com", "hello", "body");
|
||||
$this->testedEmailPlugin->sendEmail("test@email.com", array(), "hello", "body");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,7 +177,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase
|
|||
$this->mockMailer->expects($this->once())
|
||||
->method('send')
|
||||
->with($this->isInstanceOf('\Swift_Message'), $this->anything());
|
||||
$this->testedEmailPlugin->sendEmail($toAddress, $subject, $body);
|
||||
$this->testedEmailPlugin->sendEmail($toAddress, array(), $subject, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,7 +197,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase
|
|||
$actualMail = null;
|
||||
$this->catchMailPassedToSend($actualMail);
|
||||
|
||||
$this->testedEmailPlugin->sendEmail($toAddress, $subject, $body);
|
||||
$this->testedEmailPlugin->sendEmail($toAddress, array(), $subject, $body);
|
||||
|
||||
$this->assertSystemMail(
|
||||
$toAddress,
|
||||
|
|
51
Tests/PHPCI/Plugin/Util/ComposerPluginInformationTest.php
Normal file
51
Tests/PHPCI/Plugin/Util/ComposerPluginInformationTest.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Tests\Util;
|
||||
|
||||
use PHPCI\Plugin\Util\ComposerPluginInformation;
|
||||
|
||||
class ComposerPluginInformationTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var ComposerPluginInformation
|
||||
*/
|
||||
protected $testedInformation;
|
||||
|
||||
protected function setUpFromFile($file)
|
||||
{
|
||||
$this->testedInformation = ComposerPluginInformation::buildFromYaml($file);
|
||||
}
|
||||
|
||||
protected function phpciSetup()
|
||||
{
|
||||
$this->setUpFromFile(
|
||||
__DIR__ . "/../../../../vendor/composer/installed.json"
|
||||
);
|
||||
}
|
||||
|
||||
public function testBuildFromYaml_ReturnsInstance()
|
||||
{
|
||||
$this->phpciSetup();
|
||||
$this->assertInstanceOf(
|
||||
'\PHPCI\Plugin\Util\ComposerPluginInformation',
|
||||
$this->testedInformation
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetInstalledPlugins_ReturnsStdClassArray()
|
||||
{
|
||||
$this->phpciSetup();
|
||||
$plugins = $this->testedInformation->getInstalledPlugins();
|
||||
$this->assertInternalType("array", $plugins);
|
||||
$this->assertContainsOnly("stdClass", $plugins);
|
||||
}
|
||||
|
||||
public function testGetPluginClasses_ReturnsStringArray()
|
||||
{
|
||||
$this->phpciSetup();
|
||||
$classes = $this->testedInformation->getPluginClasses();
|
||||
$this->assertInternalType("array", $classes);
|
||||
$this->assertContainsOnly("string", $classes);
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ class ExecutorTest extends ProphecyTestCase
|
|||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->mockBuildLogger = $this->prophesize('\PHPCI\BuildLogger');
|
||||
$this->mockBuildLogger = $this->prophesize('\PHPCI\Logging\BuildLogger');
|
||||
$this->mockFactory = $this->prophesize('\PHPCI\Plugin\Util\Factory');
|
||||
$this->testedExecutor = new Executor($this->mockFactory->reveal(), $this->mockBuildLogger->reveal());
|
||||
}
|
||||
|
|
26
Tests/PHPCI/Plugin/Util/FilesPluginInformationTest.php
Normal file
26
Tests/PHPCI/Plugin/Util/FilesPluginInformationTest.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Tests\Util;
|
||||
|
||||
use PHPCI\Plugin\Util\FilesPluginInformation;
|
||||
|
||||
class FilesPluginInformationTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function testGetInstalledPlugins_returnsObjectes()
|
||||
{
|
||||
$pluginDirPath = realpath(__DIR__ . "/../../../../PHPCI/Plugin/");
|
||||
$test = FilesPluginInformation::newFromDir($pluginDirPath);
|
||||
$pluginInfos = $test->getInstalledPlugins();
|
||||
$this->assertContainsOnlyInstancesOf('stdClass', $pluginInfos);
|
||||
}
|
||||
|
||||
public function testGetPluginClasses_returnsStrings()
|
||||
{
|
||||
$pluginDirPath = realpath(__DIR__ . "/../../../../PHPCI/Plugin/");
|
||||
$test = FilesPluginInformation::newFromDir($pluginDirPath);
|
||||
$pluginInfos = $test->getPluginClasses();
|
||||
$this->assertContainsOnly('string', $pluginInfos);
|
||||
}
|
||||
}
|
||||
|
44
Tests/bootstrap.php
Normal file
44
Tests/bootstrap.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2013, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link http://www.phptesting.org/
|
||||
*/
|
||||
|
||||
// Let PHP take a guess as to the default timezone, if the user hasn't set one:
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set up a basic autoloader for PHPCI:
|
||||
$autoload = function ($class) {
|
||||
$file = str_replace(array('\\', '_'), '/', $class);
|
||||
$file .= '.php';
|
||||
|
||||
if (substr($file, 0, 1) == '/') {
|
||||
$file = substr($file, 1);
|
||||
}
|
||||
|
||||
if (is_file(dirname(__DIR__) . '/' . $file)) {
|
||||
include(dirname(__DIR__) . '/' . $file);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
spl_autoload_register($autoload, true, true);
|
||||
|
||||
// Load Composer autoloader:
|
||||
require_once(dirname(__DIR__) . '/vendor/autoload.php');
|
||||
|
||||
// Load configuration if present:
|
||||
$conf = array();
|
||||
$conf['b8']['app']['namespace'] = 'PHPCI';
|
||||
$conf['b8']['app']['default_controller'] = 'Home';
|
||||
$conf['b8']['view']['path'] = dirname(__DIR__) . '/PHPCI/View/';
|
||||
|
||||
if (file_exists(dirname(__DIR__) . '/PHPCI/config.yml')) {
|
||||
$config = new b8\Config($conf);
|
||||
$config->loadYaml(dirname(__DIR__) . '/PHPCI/config.yml');
|
||||
}
|
||||
|
||||
require_once(dirname(__DIR__) . '/vars.php');
|
|
@ -34,11 +34,11 @@
|
|||
},
|
||||
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.*",
|
||||
"phpspec/prophecy-phpunit": "1.*"
|
||||
},
|
||||
|
||||
"suggest": {
|
||||
"phpunit/phpunit": "PHP unit testing framework",
|
||||
"phpmd/phpmd": "PHP Mess Detector",
|
||||
"sebastian/phpcpd": "PHP Copy/Paste Detector",
|
||||
"squizlabs/php_codesniffer": "PHP Code Sniffer",
|
||||
|
|
64
composer.lock
generated
64
composer.lock
generated
|
@ -7,16 +7,16 @@
|
|||
"packages": [
|
||||
{
|
||||
"name": "block8/b8framework",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Block8/b8framework.git",
|
||||
"reference": "0497ae34ba7ef828db23b35a1f75d4debfa7eed5"
|
||||
"reference": "f643e0d3497599016cb62611ceb9288710423121"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Block8/b8framework/zipball/0497ae34ba7ef828db23b35a1f75d4debfa7eed5",
|
||||
"reference": "0497ae34ba7ef828db23b35a1f75d4debfa7eed5",
|
||||
"url": "https://api.github.com/repos/Block8/b8framework/zipball/f643e0d3497599016cb62611ceb9288710423121",
|
||||
"reference": "f643e0d3497599016cb62611ceb9288710423121",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -50,7 +50,7 @@
|
|||
"mvc",
|
||||
"php"
|
||||
],
|
||||
"time": "2013-10-09 14:06:12"
|
||||
"time": "2014-02-24 11:25:23"
|
||||
},
|
||||
{
|
||||
"name": "ircmaxell/password-compat",
|
||||
|
@ -155,16 +155,16 @@
|
|||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
"version": "v1.1.0",
|
||||
"version": "v1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fabpot/Pimple.git",
|
||||
"reference": "471c7d7c52ad6594e17b8ec33efdd1be592b5d83"
|
||||
"reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fabpot/Pimple/zipball/471c7d7c52ad6594e17b8ec33efdd1be592b5d83",
|
||||
"reference": "471c7d7c52ad6594e17b8ec33efdd1be592b5d83",
|
||||
"url": "https://api.github.com/repos/fabpot/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
|
||||
"reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -188,7 +188,9 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
|
||||
|
@ -197,7 +199,7 @@
|
|||
"container",
|
||||
"dependency injection"
|
||||
],
|
||||
"time": "2013-09-19 04:53:08"
|
||||
"time": "2013-11-22 08:30:29"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
|
@ -288,17 +290,17 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.4.0",
|
||||
"version": "v2.4.2",
|
||||
"target-dir": "Symfony/Component/Console",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Console.git",
|
||||
"reference": "3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c"
|
||||
"reference": "940f217cbc3c8a33e5403e7c595495c4884400fe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c",
|
||||
"reference": "3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/940f217cbc3c8a33e5403e7c595495c4884400fe",
|
||||
"reference": "940f217cbc3c8a33e5403e7c595495c4884400fe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -328,7 +330,9 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
|
@ -337,21 +341,21 @@
|
|||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-11-27 09:10:40"
|
||||
"time": "2014-02-11 13:52:09"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.4.0",
|
||||
"version": "v2.4.2",
|
||||
"target-dir": "Symfony/Component/Yaml",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Yaml.git",
|
||||
"reference": "1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5"
|
||||
"reference": "bb6ddaf8956139d1b8c360b4b713ed0138e876b3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5",
|
||||
"reference": "1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/bb6ddaf8956139d1b8c360b4b713ed0138e876b3",
|
||||
"reference": "bb6ddaf8956139d1b8c360b4b713ed0138e876b3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -375,7 +379,9 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
|
@ -384,22 +390,22 @@
|
|||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-11-26 16:40:27"
|
||||
"time": "2014-01-07 13:28:54"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.0.4",
|
||||
"version": "1.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "79d9c8bd94801bffbf9b56964f6438762da6d8cd"
|
||||
"reference": "976a65af02a2a0e17ce6c949f7b43437205628bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/79d9c8bd94801bffbf9b56964f6438762da6d8cd",
|
||||
"reference": "79d9c8bd94801bffbf9b56964f6438762da6d8cd",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/976a65af02a2a0e17ce6c949f7b43437205628bb",
|
||||
"reference": "976a65af02a2a0e17ce6c949f7b43437205628bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -408,7 +414,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -441,7 +447,7 @@
|
|||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2013-08-10 11:11:45"
|
||||
"time": "2014-01-24 11:03:43"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy-phpunit",
|
||||
|
|
4
console
Normal file → Executable file
4
console
Normal file → Executable file
|
@ -18,9 +18,10 @@ use PHPCI\Command\UpdateCommand;
|
|||
use PHPCI\Command\InstallCommand;
|
||||
use PHPCI\Command\DaemonCommand;
|
||||
use PHPCI\Command\PollCommand;
|
||||
use PHPCI\Command\CreateAdminCommand;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
$loggerConfig = \PHPCI\Helper\LoggerConfig::newFromFile(__DIR__ . "/loggerconfig.php");
|
||||
$loggerConfig = \PHPCI\Logging\LoggerConfig::newFromFile(__DIR__ . "/loggerconfig.php");
|
||||
|
||||
$application = new Application();
|
||||
|
||||
|
@ -30,5 +31,6 @@ $application->add(new UpdateCommand($loggerConfig->getFor('UpdateCommand')));
|
|||
$application->add(new GenerateCommand);
|
||||
$application->add(new DaemonCommand($loggerConfig->getFor('DaemonCommand')));
|
||||
$application->add(new PollCommand($loggerConfig->getFor('PollCommand')));
|
||||
$application->add(new CreateAdminCommand);
|
||||
|
||||
$application->run();
|
||||
|
|
|
@ -15,6 +15,8 @@ require('bootstrap.php');
|
|||
use PHPCI\Command\DaemoniseCommand;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
$loggerConfig = \PHPCI\Logging\LoggerConfig::newFromFile(__DIR__ . "/loggerconfig.php");
|
||||
|
||||
$application = new Application();
|
||||
$application->add(new DaemoniseCommand);
|
||||
$application->add(new DaemoniseCommand($loggerConfig->getFor('DaemoniseCommand')));
|
||||
$application->run();
|
||||
|
|
14
phpci.yml
14
phpci.yml
|
@ -5,11 +5,6 @@ build_settings:
|
|||
- "Tests"
|
||||
- "PHPCI/Command" # PHPMD complains about un-used parameters, but they are required.
|
||||
- "public/install.php" # PHPCS really doesn't like PHP mixed with HTML (and so it shouldn't)
|
||||
irc:
|
||||
server: "irc.freenode.net"
|
||||
port: 6667
|
||||
room: "#phpci"
|
||||
nick: "phpcidev"
|
||||
|
||||
test:
|
||||
php_mess_detector:
|
||||
|
@ -17,10 +12,7 @@ test:
|
|||
standard: "PSR2"
|
||||
php_loc:
|
||||
|
||||
success:
|
||||
irc:
|
||||
message: "Build Success. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%"
|
||||
|
||||
failure:
|
||||
irc:
|
||||
message: "Build Failed. %PROJECT_TITLE% - %COMMIT% - %BUILD_URI%"
|
||||
email:
|
||||
committer: true
|
||||
cc: ["php-ci@googlegroups.com"]
|
||||
|
|
24
phpunit.xml
Normal file
24
phpunit.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false"
|
||||
bootstrap="./Tests/bootstrap.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="PHPCI Helper Test Suite">
|
||||
<directory suffix="Test.php">./Tests/PHPCI/Helper</directory>
|
||||
</testsuite>
|
||||
<testsuite name="PHPCI Logging Test Suite">
|
||||
<directory suffix="Test.php">./Tests/PHPCI/Logging</directory>
|
||||
</testsuite>
|
||||
<testsuite name="PHPCI Plugin Test Suite">
|
||||
<directory suffix="Test.php">./Tests/PHPCI/Plugin</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
36
public/assets/js/init.js
Normal file
36
public/assets/js/init.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @file init.js
|
||||
* Initialization of frontend of the application goes here
|
||||
*
|
||||
* @author Pavel Pavlov <Pavel.Pavlov@alera.ru>
|
||||
* @date 12/31/13
|
||||
* @time 3:44 AM
|
||||
* @license LICENSE.md
|
||||
*
|
||||
* @package PHPCI
|
||||
*/
|
||||
|
||||
$(function () {
|
||||
$('#latest-builds').on('latest-builds:reload', bindAppDeleteEvents);
|
||||
$('#latest-builds').trigger('latest-builds:reload');
|
||||
});
|
||||
|
||||
function bindAppDeleteEvents () {
|
||||
$('.phpci-app-delete-build').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
confirmDelete(e.target.href, 'Build').onClose = function () {
|
||||
refreshBuildsTable();
|
||||
};
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.phpci-app-delete-user').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
confirmDelete(e.target.href, 'User', true);
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
|
@ -81,6 +81,11 @@ if ($installOK && strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') {
|
|||
*/
|
||||
require_once(PHPCI_DIR . 'vendor/autoload.php');
|
||||
|
||||
/**
|
||||
* Temporary save phpci URL for redirect after install ($config is replaced in bootstrap.php)
|
||||
*/
|
||||
$phpciUrl = $config['phpci']['url'];
|
||||
|
||||
/**
|
||||
* Write config file:
|
||||
*/
|
||||
|
@ -101,8 +106,8 @@ if ($installOK && strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') {
|
|||
* Create database:
|
||||
*/
|
||||
$dbhost = $config['b8']['database']['servers']['write'][0];
|
||||
$dbname = $config['b8']['database']['name'];
|
||||
$dbuser = $config['b8']['database']['username'];
|
||||
$dbname = $config['b8']['database']['name'] ?: 'phpci';
|
||||
$dbuser = $config['b8']['database']['username'] ?: 'phpci';
|
||||
$dbpass = $config['b8']['database']['password'];
|
||||
|
||||
$pdo = new PDO('mysql:host=' . $dbhost, $dbuser, $dbpass);
|
||||
|
@ -139,7 +144,7 @@ if ($installOK && strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') {
|
|||
$store->save($user);
|
||||
}
|
||||
|
||||
$formAction = '/session/login';
|
||||
$formAction = rtrim( $phpciUrl, '/' ) . '/session/login';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue