This commit is contained in:
Dmitry Khomutov 2016-04-25 23:30:23 +06:00
parent 8e970853f6
commit ca2f5ed197
30 changed files with 180 additions and 337 deletions

View file

@ -1,13 +1,13 @@
b8: b8:
database: database:
servers: servers:
read: localhost read: localhost
write: localhost write: localhost
name: phpci name: phpci
username: root username: root
password: root password: root
phpci: phpci:
url: 'http://phpci.local' url: 'http://phpci.local'
worker: worker:
host: localhost host: localhost
queue: phpci queue: phpci

View file

@ -18,7 +18,7 @@ if (!is_array($writeServers)) {
$conf = [ $conf = [
'paths' => [ 'paths' => [
'migrations' => 'PHPCI/Migrations', 'migrations' => 'src/PHPCI/Migrations',
], ],
'environments' => [ 'environments' => [
'default_migration_table' => 'migration', 'default_migration_table' => 'migration',

View file

@ -1,5 +1,6 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php <?php
/** /**
* PHPCI - Continuous Integration for PHP * PHPCI - Continuous Integration for PHP
* *

View file

@ -1,5 +1,6 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php <?php
/** /**
* PHPCI - Continuous Integration for PHP * PHPCI - Continuous Integration for PHP
* *

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHPCI - Continuous Integration for PHP * PHPCI - Continuous Integration for PHP
* *

View file

@ -5,7 +5,6 @@ namespace b8;
use b8\Exception\HttpException\NotFoundException; use b8\Exception\HttpException\NotFoundException;
use b8\Http; use b8\Http;
use b8\View; use b8\View;
use b8\Controller;
use b8\Http\Response; use b8\Http\Response;
use b8\Http\Request; use b8\Http\Request;

View file

@ -18,8 +18,8 @@ class Config
} }
/** /**
* @var array * @var array
*/ */
protected $config = []; protected $config = [];
public function __construct($settings = null) public function __construct($settings = null)
@ -51,11 +51,11 @@ class Config
} }
/** /**
* Get a configuration value by key, returning a default value if not set. * Get a configuration value by key, returning a default value if not set.
* @param $key string * @param $key string
* @param $default mixed * @param $default mixed
* @return mixed * @return mixed
*/ */
public function get($key, $default = null) public function get($key, $default = null)
{ {
$keyParts = explode('.', $key); $keyParts = explode('.', $key);
@ -81,52 +81,56 @@ class Config
} }
/** /**
* Set a value by key. * Set a value by key.
* @param $key string * @param $key string
* @param $value mixed * @param $value mixed
*/ *
* @return boolean
*/
public function set($key, $value = null) public function set($key, $value = null)
{ {
$this->config[$key] = $value; $this->config[$key] = $value;
return true;
} }
/** /**
* Set an array of values. * Set an array of values.
*/ */
public function setArray($array) public function setArray($array)
{ {
self::deepMerge($this->config, $array); self::deepMerge($this->config, $array);
} }
/** /**
* Short-hand syntax for get() * Short-hand syntax for get()
* @see Config::get() * @see Config::get()
*/ */
public function __get($key) public function __get($key)
{ {
return $this->get($key); return $this->get($key);
} }
/** /**
* Short-hand syntax for set() * Short-hand syntax for set()
* @see Config::set() * @see Config::set()
*/ */
public function __set($key, $value = null) public function __set($key, $value = null)
{ {
return $this->set($key, $value); return $this->set($key, $value);
} }
/** /**
* Is set * Is set
*/ */
public function __isset($key) public function __isset($key)
{ {
return isset($this->config[$key]); return isset($this->config[$key]);
} }
/** /**
* Unset * Unset
*/ */
public function __unset($key) public function __unset($key)
{ {
unset($this->config[$key]); unset($this->config[$key]);

View file

@ -1,224 +0,0 @@
<?php
namespace b8\Controller;
use b8\Controller,
b8\Type\RestUser,
b8\Store\Factory,
b8\Exception\HttpException;
class RestController extends Controller
{
const SEARCHTYPE_AND = 'AND';
const SEARCHTYPE_OR = 'OR';
public $requiresAuthentication = true;
public $updateLastAction = true;
/**
* @var \b8\Type\RestUser
*/
protected $activeUser;
protected $where = [];
protected $limit = null;
protected $offset = null;
protected $joins = [];
protected $arrayDepth = 2;
protected $params = null;
protected $order = [];
protected $group = null;
protected $manualJoins = [];
protected $manualWheres = [];
protected $searchType = self::SEARCHTYPE_AND;
protected $_resourceName = null;
protected $_modelName = null;
protected $_tableName = null;
protected $_modelClass = null;
public function init()
{
}
protected function setControllerView()
{
}
protected function setView()
{
}
public function handleAction($action, $actionParams)
{
$response = call_user_func_array([$this, $action], $actionParams);
$this->response->setContent($response);
return $this->response;
}
public function setActiveUser(RestUser $user)
{
$this->activeUser = $user;
}
public function getActiveUser()
{
return $this->activeUser;
}
public function index()
{
if (!$this->activeUser->checkPermission('canRead', $this->_resourceName)) {
throw new HttpException\ForbiddenException('You do not have permission do this.');
}
$this->where = $this->_parseWhere();
$this->limit = is_null($this->limit) ? $this->getParam('limit', 25) : $this->limit;
$this->offset = is_null($this->offset) ? $this->getParam('offset', 0) : $this->offset;
$this->order = is_null($this->order) || !count($this->order) ? $this->getParam('order', []) : $this->order;
$this->group = is_null($this->group) || !count($this->group) ? $this->getParam('group', null) : $this->group;
$this->searchType = $this->getParam('searchType', self::SEARCHTYPE_AND);
$store = Factory::getStore($this->_modelName);
$data = $store->getWhere($this->where, $this->limit, $this->offset, $this->joins, $this->order,
$this->manualJoins, $this->group, $this->manualWheres, $this->searchType);
$rtn = [
'debug' => [
'where' => $this->where,
'searchType' => $this->searchType,
],
'limit' => $this->limit,
'offset' => $this->offset,
'total' => $data['count'],
'items' => []
];
foreach ($data['items'] as $item) {
$rtn['items'][] = $item->toArray($this->arrayDepth);
}
return $rtn;
}
/**
*
*/
protected function _parseWhere()
{
$clauses = [
'fuzzy' => 'like',
'gt' => '>',
'gte' => '>=',
'lt' => '<',
'lte' => '<=',
'neq' => '!=',
'between' => 'between',
];
$where = $this->getParam('where', []);
$where = array_merge($where, $this->where);
if (count($where)) {
foreach ($where as &$value) {
if (!is_array($value) || !isset($value['operator'])) {
if (is_array($value) && count($value) == 1) {
$value = array_shift($value);
}
$value = [
'operator' => '=',
'value' => $value,
];
}
}
foreach ($clauses as $clause => $operator) {
$fields = $this->getParam($clause, []);
if (count($clause)) {
if (!is_array($fields)) {
$fields = [$fields];
}
foreach ($fields as $field) {
if (isset($where[$field])) {
$where[$field]['operator'] = $operator;
if ($operator == 'like') {
$where[$field]['value'] = str_replace(' ', '%', $where[$field]['value']);
}
}
}
}
}
}
return $where;
}
public function get($key)
{
if (!$this->activeUser->checkPermission('canRead', $this->_resourceName)) {
throw new HttpException\ForbiddenException('You do not have permission do this.');
}
$rtn = Factory::getStore($this->_modelName)->getByPrimaryKey($key);
if (is_object($rtn) && method_exists($rtn, 'toArray')) {
$rtn = $rtn->toArray($this->arrayDepth);
}
return [strtolower($this->_modelName) => $rtn];
}
public function put($key)
{
if (!$this->activeUser->checkPermission('canEdit', $this->_resourceName)) {
throw new HttpException\ForbiddenException('You do not have permission do this.');
}
$store = Factory::getStore($this->_modelName);
if ($obj = $store->getByPrimaryKey($key)) {
$obj->setValues($this->getParams());
$rtn = $store->save($obj);
return [strtolower($this->_modelName) => $rtn->toArray($this->arrayDepth)];
} else {
return null;
}
}
public function post()
{
if (!$this->activeUser->checkPermission('canCreate', $this->_resourceName)) {
throw new HttpException\ForbiddenException('You do not have permission do this.');
}
$store = Factory::getStore($this->_modelName);
$modelClass = $this->_modelClass;
$obj = new $modelClass();
$obj->setValues($this->getParams());
$rtn = $store->save($obj);
return [strtolower($this->_modelName) => $rtn->toArray($this->arrayDepth)];
}
public function delete($key)
{
if (!$this->activeUser->checkPermission('canDelete', $this->_resourceName)) {
throw new HttpException\ForbiddenException('You do not have permission do this.');
}
$store = Factory::getStore($this->_modelName);
try {
if ($obj = $store->getByPrimaryKey($key)) {
$store->delete($obj);
return ['deleted' => true];
}
} catch (\Exception $ex) {
}
return ['deleted' => false];
}
}

View file

@ -255,4 +255,4 @@ class Map
return $fkMethod; return $fkMethod;
} }
} }

View file

@ -128,4 +128,4 @@ class Response
{ {
return $this->flush(); return $this->flush();
} }
} }

View file

@ -2,8 +2,7 @@
namespace b8\Http; namespace b8\Http;
use b8\Application; use b8\Application, b8\Config;
use b8\Config;
class Router class Router
{ {

View file

@ -1,12 +0,0 @@
<?php
namespace b8\View;
class UserView extends Template
{
public function __construct($string)
{
trigger_error('Use of UserView is now deprecated. Please use Template instead.', E_USER_NOTICE);
parent::__construct($string);
}
}

View file

@ -41,6 +41,7 @@ class InstallCommand extends Command
->setName('phpci:install') ->setName('phpci:install')
->addOption('url', null, InputOption::VALUE_OPTIONAL, Lang::get('installation_url')) ->addOption('url', null, InputOption::VALUE_OPTIONAL, Lang::get('installation_url'))
->addOption('db-host', null, InputOption::VALUE_OPTIONAL, Lang::get('db_host')) ->addOption('db-host', null, InputOption::VALUE_OPTIONAL, Lang::get('db_host'))
->addOption('db-port', null, InputOption::VALUE_OPTIONAL, Lang::get('db_port'))
->addOption('db-name', null, InputOption::VALUE_OPTIONAL, Lang::get('db_name')) ->addOption('db-name', null, InputOption::VALUE_OPTIONAL, Lang::get('db_name'))
->addOption('db-user', null, InputOption::VALUE_OPTIONAL, Lang::get('db_user')) ->addOption('db-user', null, InputOption::VALUE_OPTIONAL, Lang::get('db_user'))
->addOption('db-pass', null, InputOption::VALUE_OPTIONAL, Lang::get('db_pass')) ->addOption('db-pass', null, InputOption::VALUE_OPTIONAL, Lang::get('db_pass'))
@ -293,6 +294,10 @@ class InstallCommand extends Command
$dbHost = $dialog->ask($output, Lang::get('enter_db_host'), 'localhost'); $dbHost = $dialog->ask($output, Lang::get('enter_db_host'), 'localhost');
} }
if (!$dbPort = $input->getOption('db-port')) {
$dbPort = $dialog->ask($output, Lang::get('enter_db_port'), '3306');
}
if (!$dbName = $input->getOption('db-name')) { if (!$dbName = $input->getOption('db-name')) {
$dbName = $dialog->ask($output, Lang::get('enter_db_name'), 'phpci'); $dbName = $dialog->ask($output, Lang::get('enter_db_name'), 'phpci');
} }
@ -305,11 +310,12 @@ class InstallCommand extends Command
$dbPass = $dialog->askHiddenResponse($output, Lang::get('enter_db_pass')); $dbPass = $dialog->askHiddenResponse($output, Lang::get('enter_db_pass'));
} }
$db['servers']['read'] = $dbHost; $db['servers']['read'] = $dbHost;
$db['servers']['write'] = $dbHost; $db['servers']['write'] = $dbHost;
$db['name'] = $dbName; $db['port'] = $dbPort;
$db['username'] = $dbUser; $db['name'] = $dbName;
$db['password'] = $dbPass; $db['username'] = $dbUser;
$db['password'] = $dbPass;
return $db; return $db;
} }
@ -324,7 +330,7 @@ class InstallCommand extends Command
{ {
try { try {
$pdo = new PDO( $pdo = new PDO(
'mysql:host='.$db['servers']['write'].';dbname='.$db['name'], 'mysql:host='.$db['servers']['write'].';port='.$db['port'].'dbname='.$db['name'],
$db['username'], $db['username'],
$db['password'], $db['password'],
[ [

View file

@ -258,7 +258,7 @@ class ProjectController extends PHPCI\Controller
if ($values['type'] == "gitlab") { if ($values['type'] == "gitlab") {
$accessInfo = $project->getAccessInformation(); $accessInfo = $project->getAccessInformation();
$reference = $accessInfo["user"].'@'.$accessInfo["domain"].':' . $project->getReference().".git"; $reference = $accessInfo["user"].'@'.$accessInfo["domain"].':' . $accessInfo["port"] . '/' . ltrim($project->getReference(), '/') . ".git";
$values['reference'] = $reference; $values['reference'] = $reference;
} }

View file

@ -293,7 +293,14 @@ class WebhookController extends \b8\Controller
$url = $payload['pull_request']['commits_url']; $url = $payload['pull_request']['commits_url'];
$http = new \b8\HttpClient(); $http = new \b8\HttpClient();
$http->setHeaders($headers); $http->setHeaders($headers);
$response = $http->get($url);
//for large pull requests, allow grabbing more then the default number of commits
$custom_per_page = \b8\Config::getInstance()->get('phpci.github.per_page');
$params = [];
if ($custom_per_page) {
$params["per_page"] = $custom_per_page;
}
$response = $http->get($url, $params);
// Check we got a success response: // Check we got a success response:
if (!$response['success']) { if (!$response['success']) {

View file

@ -88,7 +88,7 @@ class Lang
{ {
if (in_array($language, self::$languages)) { if (in_array($language, self::$languages)) {
self::$language = $language; self::$language = $language;
self::$strings = self::loadLanguage(); self::$strings = self::loadLanguage();
return true; return true;
} }
@ -177,12 +177,11 @@ class Lang
return null; return null;
} }
$strings = include_once($langFile); $strings = include($langFile);
if (is_null($strings) || !is_array($strings) || !count($strings)) { if (is_null($strings) || !is_array($strings) || !count($strings)) {
return null; return null;
} }
return $strings; return $strings;
} }

View file

@ -349,6 +349,7 @@ PHPCI',
'enter_phpci_url' => 'Your PHPCI URL ("http://phpci.local" for example): ', 'enter_phpci_url' => 'Your PHPCI URL ("http://phpci.local" for example): ',
'enter_db_host' => 'Please enter your MySQL host [localhost]: ', 'enter_db_host' => 'Please enter your MySQL host [localhost]: ',
'enter_db_port' => 'Please enter your MySQL port [3306]: ',
'enter_db_name' => 'Please enter your MySQL database name [phpci]: ', 'enter_db_name' => 'Please enter your MySQL database name [phpci]: ',
'enter_db_user' => 'Please enter your MySQL username [phpci]: ', 'enter_db_user' => 'Please enter your MySQL username [phpci]: ',
'enter_db_pass' => 'Please enter your MySQL password: ', 'enter_db_pass' => 'Please enter your MySQL password: ',
@ -449,6 +450,4 @@ PHPCI',
'php_unit' => 'PHP Unit', 'php_unit' => 'PHP Unit',
'php_cpd' => 'PHP Copy/Paste Detector', 'php_cpd' => 'PHP Copy/Paste Detector',
'php_docblock_checker' => 'PHP Docblock Checker', 'php_docblock_checker' => 'PHP Docblock Checker',
'behat' => 'Behat',
'technical_debt' => 'Technical Debt',
]; ];

View file

@ -152,6 +152,9 @@ PHPCI',
<a href="https://bitbucket.org/%s/admin/services"> <a href="https://bitbucket.org/%s/admin/services">
Services</a> de votre dépôt Bitbucket.', Services</a> de votre dépôt Bitbucket.',
'errors' => 'Erreurs',
'information' => 'Informations',
// View Build // View Build
'build_x_not_found' => 'Le Build avec l\'ID %d n\'existe pas.', 'build_x_not_found' => 'Le Build avec l\'ID %d n\'existe pas.',
'build_n' => 'Build %d', 'build_n' => 'Build %d',
@ -187,6 +190,7 @@ PHPCI',
'phpmd' => 'PHP Mess Detector', 'phpmd' => 'PHP Mess Detector',
'phpspec' => 'PHP Spec', 'phpspec' => 'PHP Spec',
'phpunit' => 'PHP Unit', 'phpunit' => 'PHP Unit',
'behat' => 'Behat',
'file' => 'Fichier', 'file' => 'Fichier',
'line' => 'Ligne', 'line' => 'Ligne',
@ -406,5 +410,11 @@ PHPCI',
'build_file_missing' => 'Le fichier de build spécifié n\'existe pas.', 'build_file_missing' => 'Le fichier de build spécifié n\'existe pas.',
'property_file_missing' => 'Le fichier de propriété spécifié n\'existe pas.', 'property_file_missing' => 'Le fichier de propriété spécifié n\'existe pas.',
'could_not_process_report' => 'Impossible de traiter le rapport généré par cet outil.', 'could_not_process_report' => 'Impossible de traiter le rapport généré par cet outil.',
'shell_not_enabled' => 'Le plugn shell n\'est pas activé. Merci de l\'activer via le fichier config.yml.' 'shell_not_enabled' => 'Le plugn shell n\'est pas activé. Merci de l\'activer via le fichier config.yml.',
// Error Levels:
'critical' => 'Critique',
'high' => 'Haut',
'normal' => 'Normal',
'low' => 'Base',
]; ];

View file

@ -158,6 +158,8 @@ PHPCI',
'group_save' => 'Сохранить группу', 'group_save' => 'Сохранить группу',
// View Build // View Build
'errors' => 'Ошибки',
'information' => 'Информация',
'build_x_not_found' => 'Сборки с ID %d не существует.', 'build_x_not_found' => 'Сборки с ID %d не существует.',
'build_n' => 'Сборка %d', 'build_n' => 'Сборка %d',
'rebuild_now' => 'Пересобрать сейчас', 'rebuild_now' => 'Пересобрать сейчас',
@ -215,8 +217,8 @@ PHPCI',
'build_created' => 'Сборка создана', 'build_created' => 'Сборка создана',
'build_started' => 'Сборка запущена', 'build_started' => 'Сборка запущена',
'build_finished' => 'Сборка окончена', 'build_finished' => 'Сборка окончена',
'test_message' => 'Message', 'test_message' => 'Сообщение',
'test_no_message' => 'No message', 'test_no_message' => 'Нет сообщений',
'test_success' => 'Успешно: %d', 'test_success' => 'Успешно: %d',
'test_fail' => 'Провалено: %d', 'test_fail' => 'Провалено: %d',
'test_skipped' => 'Пропущено: %d', 'test_skipped' => 'Пропущено: %d',
@ -336,6 +338,7 @@ PHPCI',
'enter_phpci_url' => 'URL-адрес вашего PHPCI (например: "http://phpci.local"): ', 'enter_phpci_url' => 'URL-адрес вашего PHPCI (например: "http://phpci.local"): ',
'enter_db_host' => 'Пожалуйста, введите хост MySQL [localhost]: ', 'enter_db_host' => 'Пожалуйста, введите хост MySQL [localhost]: ',
'enter_db_port' => 'Пожалуйста, введите порт MySQL [3306]: ',
'enter_db_name' => 'Пожалуйста, введите имя базы данных MySQL [phpci]: ', 'enter_db_name' => 'Пожалуйста, введите имя базы данных MySQL [phpci]: ',
'enter_db_user' => 'Пожалуйста, введите пользователя MySQL [phpci]: ', 'enter_db_user' => 'Пожалуйста, введите пользователя MySQL [phpci]: ',
'enter_db_pass' => 'Пожалуйста, введите пароль MySQL: ', 'enter_db_pass' => 'Пожалуйста, введите пароль MySQL: ',
@ -418,5 +421,18 @@ PHPCI',
'build_file_missing' => 'Указанного файла сборки не существует.', 'build_file_missing' => 'Указанного файла сборки не существует.',
'property_file_missing' => 'Указанного файла сборки не существует.', 'property_file_missing' => 'Указанного файла сборки не существует.',
'could_not_process_report' => 'Невозможно обработать отчет этой утилиты.', 'could_not_process_report' => 'Невозможно обработать отчет этой утилиты.',
'shell_not_enabled' => 'Плагин shell не включен. Пожалуйста, включите его в файле config.yml.' 'shell_not_enabled' => 'Плагин shell не включен. Пожалуйста, включите его в файле config.yml.',
// Error Levels:
'critical' => 'Критичный',
'high' => 'Высокий',
'normal' => 'Нормальный',
'low' => 'Низкий',
// Plugins that generate errors:
'php_mess_detector' => 'PHP Mess Detector',
'php_code_sniffer' => 'PHP Code Sniffer',
'php_unit' => 'PHP Unit',
'php_cpd' => 'PHP Copy/Paste Detector',
'php_docblock_checker' => 'PHP Docblock Checker',
]; ];

View file

@ -20,7 +20,7 @@ class FixDatabaseColumns extends AbstractMigration
$build->changeColumn('project_id', 'integer', ['null' => false]); $build->changeColumn('project_id', 'integer', ['null' => false]);
$build->changeColumn('commit_id', 'string', ['limit' => 50, 'null' => false]); $build->changeColumn('commit_id', 'string', ['limit' => 50, 'null' => false]);
$build->changeColumn('status', 'integer', ['null' => false]); $build->changeColumn('status', 'integer', ['null' => false]);
$build->changeColumn('log', 'text', ['null' => true, 'default' => '']); $build->changeColumn('log', 'text', ['null' => true]);
$build->changeColumn('branch', 'string', ['limit' => 50, 'null' => false, 'default' => 'master']); $build->changeColumn('branch', 'string', ['limit' => 50, 'null' => false, 'default' => 'master']);
$build->changeColumn('created', 'datetime', ['null' => true]); $build->changeColumn('created', 'datetime', ['null' => true]);
$build->changeColumn('started', 'datetime', ['null' => true]); $build->changeColumn('started', 'datetime', ['null' => true]);

View file

@ -10,7 +10,7 @@ class ArchiveProject extends AbstractMigration
public function up() public function up()
{ {
$project = $this->table('project'); $project = $this->table('project');
$project->addColumn('archived', 'boolean'); $project->addColumn('archived', 'boolean', ['default' => 0]);
$project->save(); $project->save();
} }

View file

@ -13,9 +13,8 @@ class FixColumnTypes extends AbstractMigration
// Update the build log column to MEDIUMTEXT: // Update the build log column to MEDIUMTEXT:
$build = $this->table('build'); $build = $this->table('build');
$build->changeColumn('log', 'text', [ $build->changeColumn('log', 'text', [
'null' => true, 'null' => true,
'default' => '', 'limit' => MysqlAdapter::TEXT_MEDIUM,
'limit' => MysqlAdapter::TEXT_MEDIUM,
]); ]);
// Update the build meta value column to MEDIUMTEXT: // Update the build meta value column to MEDIUMTEXT:

View file

@ -47,7 +47,7 @@ class ConvertErrors extends AbstractMigration
$this->processPhpCpdMeta($meta); $this->processPhpCpdMeta($meta);
break; break;
case 'technicaldebt-data': case 'technical_debt-data':
$this->processTechnicalDebtMeta($meta); $this->processTechnicalDebtMeta($meta);
break; break;
} }

View file

@ -0,0 +1,24 @@
<?php
use Phinx\Migration\AbstractMigration;
class BranchColumnLength extends AbstractMigration
{
public function up()
{
$table = $this->table('build');
$table->changeColumn('branch', 'string', ['limit' => 250, 'null' => false, 'default' => 'master']);
$table = $this->table('project');
$table->changeColumn('branch', 'string', ['limit' => 250, 'null' => false, 'default' => 'master']);
}
public function down()
{
$table = $this->table('build');
$table->changeColumn('branch', 'string', ['limit' => 50, 'null' => false, 'default' => 'master']);
$table = $this->table('project');
$table->changeColumn('branch', 'string', ['limit' => 50, 'null' => false, 'default' => 'master']);
}
}

View file

@ -124,7 +124,7 @@ class BuildBase extends Model
], ],
'branch' => [ 'branch' => [
'type' => 'varchar', 'type' => 'varchar',
'length' => 50, 'length' => 250,
'default' => 'master', 'default' => 'master',
], ],
'created' => [ 'created' => [

View file

@ -115,7 +115,7 @@ class ProjectBase extends Model
], ],
'branch' => [ 'branch' => [
'type' => 'varchar', 'type' => 'varchar',
'length' => 50, 'length' => 250,
'default' => 'master', 'default' => 'master',
], ],
'ssh_private_key' => [ 'ssh_private_key' => [

View file

@ -28,6 +28,8 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
protected $phpci; protected $phpci;
protected $build; protected $build;
protected $nodev; protected $nodev;
protected $ignorePlatformReqs;
protected $preferSource;
/** /**
* Check if this plugin can be executed. * Check if this plugin can be executed.
@ -55,14 +57,15 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
*/ */
public function __construct(Builder $phpci, Build $build, array $options = []) public function __construct(Builder $phpci, Build $build, array $options = [])
{ {
$path = $phpci->buildPath; $path = $phpci->buildPath;
$this->phpci = $phpci; $this->phpci = $phpci;
$this->build = $build; $this->build = $build;
$this->directory = $path; $this->directory = $path;
$this->action = 'install'; $this->action = 'install';
$this->preferDist = false; $this->preferDist = false;
$this->preferSource = false; $this->preferSource = false;
$this->nodev = false; $this->nodev = false;
$this->ignorePlatformReqs = false;
if (array_key_exists('directory', $options)) { if (array_key_exists('directory', $options)) {
$this->directory = $path . DIRECTORY_SEPARATOR . $options['directory']; $this->directory = $path . DIRECTORY_SEPARATOR . $options['directory'];
@ -84,6 +87,10 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
if (array_key_exists('no_dev', $options)) { if (array_key_exists('no_dev', $options)) {
$this->nodev = (bool)$options['no_dev']; $this->nodev = (bool)$options['no_dev'];
} }
if (array_key_exists('ignore_platform_reqs', $options)) {
$this->ignorePlatformReqs = (bool)$options['ignore_platform_reqs'];
}
} }
/** /**
@ -116,6 +123,11 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
$cmd .= ' --no-dev'; $cmd .= ' --no-dev';
} }
if ($this->ignorePlatformReqs) {
$this->phpci->log('Using --ignore-platform-reqs flag');
$cmd .= ' --ignore-platform-reqs';
}
$cmd .= ' --working-dir="%s" %s'; $cmd .= ' --working-dir="%s" %s';
return $this->phpci->executeCommand($cmd, $this->directory, $this->action); return $this->phpci->executeCommand($cmd, $this->directory, $this->action);

View file

@ -146,8 +146,10 @@ class Mysql implements \PHPCI\Plugin
/** /**
* Builds the MySQL import command required to import/execute the specified file * Builds the MySQL import command required to import/execute the specified file
*
* @param string $import_file Path to file, relative to the build root * @param string $import_file Path to file, relative to the build root
* @param string $database If specified, this database is selected before execution * @param string $database If specified, this database is selected before execution
*
* @return string * @return string
*/ */
protected function getImportCommand($import_file, $database = null) protected function getImportCommand($import_file, $database = null)
@ -168,9 +170,10 @@ class Mysql implements \PHPCI\Plugin
':decomp_cmd' => $decomp_cmd, ':decomp_cmd' => $decomp_cmd,
':host' => escapeshellarg($this->host), ':host' => escapeshellarg($this->host),
':user' => escapeshellarg($this->user), ':user' => escapeshellarg($this->user),
':pass' => escapeshellarg($this->pass), ':pass' => (!$this->pass) ? '' : '-p' . escapeshellarg($this->pass),
':database' => ($database === null)? '': escapeshellarg($database), ':database' => ($database === null)? '': escapeshellarg($database),
]; ];
return strtr('cat :import_file :decomp_cmd | mysql -h:host -u:user -p:pass :database', $args);
return strtr('cat :import_file :decomp_cmd | mysql -h:host -u:user :pass :database', $args);
} }
} }

View file

@ -28,7 +28,7 @@ class Codeception implements ParserInterface
*/ */
public function __construct(Builder $phpci, $resultsXml) public function __construct(Builder $phpci, $resultsXml)
{ {
$this->phpci = $phpci; $this->phpci = $phpci;
$this->resultsXml = $resultsXml; $this->resultsXml = $resultsXml;
$this->totalTests = 0; $this->totalTests = 0;
} }
@ -38,44 +38,43 @@ class Codeception implements ParserInterface
*/ */
public function parse() public function parse()
{ {
$rtn = []; $rtn = [];
$this->results = new \SimpleXMLElement($this->resultsXml); $this->results = new \SimpleXMLElement($this->resultsXml);
// calculate total results // calculate total results
foreach ($this->results->testsuite as $testsuite) { foreach ($this->results->testsuite as $test_suite) {
$this->totalTests += (int) $testsuite['tests']; $this->totalTests += (int)$test_suite['tests'];
$this->totalTimeTaken += (float) $testsuite['time']; $this->totalTimeTaken += (float)$test_suite['time'];
$this->totalFailures += (int) $testsuite['failures']; $this->totalFailures += (int)$test_suite['failures'];
$this->totalErrors += (int) $testsuite['errors']; $this->totalErrors += (int)$test_suite['errors'];
foreach ($testsuite->testcase as $testcase) { foreach ($test_suite->testcase as $test_case) {
$testresult = [ $test_result = [
'suite' => (string) $testsuite['name'], 'suite' => (string)$test_suite['name'],
'file' => str_replace($this->phpci->buildPath, '/', (string) $testcase['file']), 'file' => str_replace($this->phpci->buildPath, '/', (string) $test_case['file']),
'name' => (string) $testcase['name'], 'name' => (string)$test_case['name'],
'feature' => (string) $testcase['feature'], 'feature' => (string)$test_case['feature'],
'assertions' => (int) $testcase['assertions'], 'assertions' => (int)$test_case['assertions'],
'time' => (float) $testcase['time'] 'time' => (float)$test_case['time']
]; ];
if (isset($testcase['class'])) { if (isset($test_case['class'])) {
$testresult['class'] = (string) $testcase['class']; $test_result['class'] = (string) $test_case['class'];
} }
// PHPUnit testcases does not have feature field. Use class::method instead // PHPUnit testcases does not have feature field. Use class::method instead
if (!$testresult['feature']) { if (!$test_result['feature']) {
$testresult['feature'] = sprintf('%s::%s', $testresult['class'], $testresult['name']); $test_result['feature'] = sprintf('%s::%s', $test_result['class'], $test_result['name']);
} }
if (isset($testcase->failure) || isset($testcase->error)) { if (isset($test_case->failure) || isset($test_case->error)) {
$testresult['pass'] = false; $test_result['pass'] = false;
$testresult['message'] = (string)$testcase->failure . (string)$testcase->error; $test_result['message'] = isset($test_case->failure) ? (string)$test_case->failure : (string)$test_case->error;
} else { } else {
$testresult['pass'] = true; $test_result['pass'] = true;
} }
$rtn[] = $testresult; $rtn[] = $test_result;
} }
} }

View file

@ -28,7 +28,7 @@ class BuildMetaStore extends BuildMetaStoreBase
public function getErrorsForUpgrade($limit) public function getErrorsForUpgrade($limit)
{ {
$query = 'SELECT * FROM build_meta $query = 'SELECT * FROM build_meta
WHERE meta_key IN (\'phpmd-data\', \'phpcs-data\', \'phpdoccheck-data\') WHERE meta_key IN (\'phpmd-data\', \'phpcs-data\', \'phpdoccheck-data\', \'technical_debt - data\')
ORDER BY id ASC LIMIT :limit'; ORDER BY id ASC LIMIT :limit';
$stmt = Database::getConnection('read')->prepare($query); $stmt = Database::getConnection('read')->prepare($query);