Merge branch 'master' of https://github.com/Block8/PHPCI
This commit is contained in:
commit
6ad3c0894e
|
@ -20,6 +20,10 @@ use PHPCI\Model\Build\BitbucketBuild;
|
|||
*/
|
||||
class BuildFactory
|
||||
{
|
||||
/**
|
||||
* Takes a generic build and returns a type-specific build model.
|
||||
* @return PHPCI\Model\Build\LocalBuild|PHPCI\Model\Build\GithubBuild|PHPCI\Model\Build\BitbucketBuild
|
||||
*/
|
||||
public static function getBuild(Build $base)
|
||||
{
|
||||
switch($base->getProject()->getType())
|
||||
|
|
|
@ -30,6 +30,9 @@ class GenerateCommand extends Command
|
|||
->setDescription('Generate models and stores from the database.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates Model and Store classes by reading database meta data.
|
||||
*/
|
||||
protected function execute()
|
||||
{
|
||||
$gen = new \b8\Database\CodeGenerator(\b8\Database::getConnection(), 'PHPCI', PHPCI_DIR . '/PHPCI/');
|
||||
|
|
|
@ -32,16 +32,21 @@ class InstallCommand extends Command
|
|||
->setDescription('Install PHPCI.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs PHPCI - Can be run more than once as long as you ^C instead of entering an email address.
|
||||
*/
|
||||
protected function execute()
|
||||
{
|
||||
// Gather initial data from the user:
|
||||
$dbHost = $this->ask('Enter your MySQL host: ');
|
||||
$dbName = $this->ask('Enter the database name PHPCI should use: ');
|
||||
$dbUser = $this->ask('Enter your MySQL username: ');
|
||||
$dbPass = $this->ask('Enter your MySQL password: ', true);
|
||||
$ciUrl = $this->ask('Your PHPCI URL (without trailing slash): ', true);
|
||||
$ciUrl = $this->ask('Your PHPCI URL (without trailing slash): ');
|
||||
$ghId = $this->ask('(Optional) Github Application ID: ', true);
|
||||
$ghSecret = $this->ask('(Optional) Github Application Secret: ', true);
|
||||
|
||||
// Create the database if it doesn't exist:
|
||||
$cmd = 'mysql -u' . $dbUser . (!empty($dbPass) ? ' -p' . $dbPass : '') . ' -h' . $dbHost .
|
||||
' -e "CREATE DATABASE IF NOT EXISTS ' . $dbName . '"';
|
||||
|
||||
|
@ -61,21 +66,28 @@ b8\Database::setReadServers(array('{$dbHost}'));
|
|||
\$registry->set('install_url', '{$ciUrl}');
|
||||
";
|
||||
|
||||
// Has the user entered Github app details? If so add those to config:
|
||||
if (!empty($ghId) && !empty($ghSecret)) {
|
||||
$str .= PHP_EOL .
|
||||
"\$registry->set('github_app', array('id' => '{$ghId}', 'secret' => '{$ghSecret}'));" .
|
||||
PHP_EOL;
|
||||
}
|
||||
|
||||
|
||||
// Write the config file and then re-bootstrap:
|
||||
file_put_contents(PHPCI_DIR . 'config.php', $str);
|
||||
|
||||
require(PHPCI_DIR . 'bootstrap.php');
|
||||
|
||||
// Update the database:
|
||||
$gen = new \b8\Database\Generator(\b8\Database::getConnection(), 'PHPCI', './PHPCI/Model/Base/');
|
||||
$gen->generate();
|
||||
|
||||
$adminEmail = $this->ask('Enter your email address: ');
|
||||
// Try to create a user account:
|
||||
$adminEmail = $this->ask('Enter your email address (leave blank if updating): ', true);
|
||||
|
||||
if (empty($adminEmail)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$adminPass = $this->ask('Enter your desired admin password: ');
|
||||
$adminName = $this->ask('Enter your name: ');
|
||||
|
||||
|
|
|
@ -33,6 +33,9 @@ class RunCommand extends Command
|
|||
->setDescription('Run all pending PHPCI builds.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls all pending builds from the database and runs them.
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
|
@ -53,6 +56,10 @@ class RunCommand extends Command
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when log entries are made in Builder / the plugins.
|
||||
* @see \PHPCI\Builder::log()
|
||||
*/
|
||||
public function logCallback($log)
|
||||
{
|
||||
$this->output->writeln($log);
|
||||
|
|
|
@ -26,6 +26,9 @@ class BitbucketController extends b8\Controller
|
|||
$this->_buildStore = Store\Factory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Bitbucket POST service.
|
||||
*/
|
||||
public function webhook($project)
|
||||
{
|
||||
$payload = json_decode($this->getParam('payload'), true);
|
||||
|
|
|
@ -26,6 +26,9 @@ class BuildController extends b8\Controller
|
|||
$this->_buildStore = b8\Store\Factory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
* View a specific build.
|
||||
*/
|
||||
public function view($buildId)
|
||||
{
|
||||
$build = $this->_buildStore->getById($buildId);
|
||||
|
@ -37,11 +40,17 @@ class BuildController extends b8\Controller
|
|||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX call to get build data:
|
||||
*/
|
||||
public function data($buildId)
|
||||
{
|
||||
die($this->getBuildData($buildId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get build data from database and json encode it:
|
||||
*/
|
||||
protected function getBuildData($buildId)
|
||||
{
|
||||
$build = $this->_buildStore->getById($buildId);
|
||||
|
@ -57,6 +66,9 @@ class BuildController extends b8\Controller
|
|||
return json_encode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a build using an existing build as a template:
|
||||
*/
|
||||
public function rebuild($buildId)
|
||||
{
|
||||
$copy = $this->_buildStore->getById($buildId);
|
||||
|
@ -73,6 +85,9 @@ class BuildController extends b8\Controller
|
|||
header('Location: /build/view/' . $build->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a build.
|
||||
*/
|
||||
public function delete($buildId)
|
||||
{
|
||||
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
|
||||
|
@ -85,6 +100,9 @@ class BuildController extends b8\Controller
|
|||
header('Location: /project/view/' . $build->getProjectId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse log for unix colours and replace with HTML.
|
||||
*/
|
||||
protected function cleanLog($log)
|
||||
{
|
||||
$log = str_replace('[0;32m', '<span style="color: green">', $log);
|
||||
|
|
|
@ -26,6 +26,9 @@ class GithubController extends b8\Controller
|
|||
$this->_buildStore = Store\Factory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Github Webhooks:
|
||||
*/
|
||||
public function webhook($project)
|
||||
{
|
||||
$payload = json_decode($this->getParam('payload'), true);
|
||||
|
|
|
@ -25,6 +25,9 @@ class IndexController extends b8\Controller
|
|||
$this->_projectStore = b8\Store\Factory::getStore('Project');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display PHPCI dashboard:
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$projects = $this->_projectStore->getWhere(array(), 50, 0, array(), array('title' => 'ASC'));
|
||||
|
@ -35,11 +38,17 @@ class IndexController extends b8\Controller
|
|||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX get latest builds table (HTML)
|
||||
*/
|
||||
public function latest()
|
||||
{
|
||||
die($this->getLatestBuildsHtml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest builds and render as a table.
|
||||
*/
|
||||
protected function getLatestBuildsHtml()
|
||||
{
|
||||
$builds = $this->_buildStore->getWhere(array(), 10, 0, array(), array('id' => 'DESC'));
|
||||
|
|
|
@ -29,6 +29,9 @@ class ProjectController extends b8\Controller
|
|||
$this->_projectStore = b8\Store\Factory::getStore('Project');
|
||||
}
|
||||
|
||||
/**
|
||||
* View a specific project.
|
||||
*/
|
||||
public function view($projectId)
|
||||
{
|
||||
$project = $this->_projectStore->getById($projectId);
|
||||
|
@ -44,6 +47,9 @@ class ProjectController extends b8\Controller
|
|||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new pending build for a project.
|
||||
*/
|
||||
public function build($projectId)
|
||||
{
|
||||
$build = new Build();
|
||||
|
@ -58,6 +64,9 @@ class ProjectController extends b8\Controller
|
|||
header('Location: /build/view/' . $build->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a project.
|
||||
*/
|
||||
public function delete($projectId)
|
||||
{
|
||||
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
|
||||
|
@ -70,12 +79,18 @@ class ProjectController extends b8\Controller
|
|||
header('Location: /');
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX get latest builds.
|
||||
*/
|
||||
public function builds($projectId)
|
||||
{
|
||||
$builds = $this->getLatestBuildsHtml($projectId);
|
||||
die($builds[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render latest builds for project as HTML table.
|
||||
*/
|
||||
protected function getLatestBuildsHtml($projectId, $start = 0)
|
||||
{
|
||||
$criteria = array('project_id' => $projectId);
|
||||
|
@ -87,6 +102,9 @@ class ProjectController extends b8\Controller
|
|||
return array($view->render(), $builds['count']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new project. Handles both the form, and processing.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
|
||||
|
@ -150,6 +168,9 @@ class ProjectController extends b8\Controller
|
|||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles log in with Github
|
||||
*/
|
||||
protected function handleGithubResponse()
|
||||
{
|
||||
$github = \b8\Registry::getInstance()->get('github_app');
|
||||
|
@ -170,6 +191,9 @@ class ProjectController extends b8\Controller
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a project. Handles both the form and processing.
|
||||
*/
|
||||
public function edit($projectId)
|
||||
{
|
||||
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
|
||||
|
@ -208,6 +232,9 @@ class ProjectController extends b8\Controller
|
|||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create add / edit project form.
|
||||
*/
|
||||
protected function projectForm($values, $type = 'add')
|
||||
{
|
||||
$form = new Form();
|
||||
|
@ -289,6 +316,9 @@ class ProjectController extends b8\Controller
|
|||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of repositories from Github's API.
|
||||
*/
|
||||
protected function getGithubRepositories()
|
||||
{
|
||||
$http = new \b8\HttpClient();
|
||||
|
|
|
@ -24,6 +24,9 @@ class SessionController extends b8\Controller
|
|||
$this->_userStore = b8\Store\Factory::getStore('User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles user login (form and processing)
|
||||
*/
|
||||
public function login()
|
||||
{
|
||||
if (b8\Registry::getInstance()->get('requestMethod') == 'POST') {
|
||||
|
@ -62,6 +65,9 @@ class SessionController extends b8\Controller
|
|||
die($view->render());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles user logout.
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
unset($_SESSION['user_id']);
|
||||
|
|
|
@ -27,6 +27,9 @@ class UserController extends b8\Controller
|
|||
$this->_userStore = b8\Store\Factory::getStore('User');
|
||||
}
|
||||
|
||||
/**
|
||||
* View user list.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$users = $this->_userStore->getWhere(array(), 1000, 0, array(), array('email' => 'ASC'));
|
||||
|
@ -36,6 +39,9 @@ class UserController extends b8\Controller
|
|||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a user - handles both form and processing.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
|
||||
|
@ -74,6 +80,9 @@ class UserController extends b8\Controller
|
|||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a user - handles both form and processing.
|
||||
*/
|
||||
public function edit($userId)
|
||||
{
|
||||
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
|
||||
|
@ -115,6 +124,9 @@ class UserController extends b8\Controller
|
|||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create user add / edit form.
|
||||
*/
|
||||
protected function userForm($values, $type = 'add')
|
||||
{
|
||||
$form = new Form();
|
||||
|
@ -155,6 +167,9 @@ class UserController extends b8\Controller
|
|||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a user.
|
||||
*/
|
||||
public function delete($userId)
|
||||
{
|
||||
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
|
||||
|
|
|
@ -21,21 +21,33 @@ use PHPCI\Builder;
|
|||
*/
|
||||
class Build extends BuildBase
|
||||
{
|
||||
/**
|
||||
* Get link to commit from another source (i.e. Github)
|
||||
*/
|
||||
public function getCommitLink()
|
||||
{
|
||||
return '#';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to branch from another source (i.e. Github)
|
||||
*/
|
||||
public function getBranchLink()
|
||||
{
|
||||
return '#';
|
||||
}
|
||||
|
||||
/**
|
||||
* Send status updates to any relevant third parties (i.e. Github)
|
||||
*/
|
||||
public function sendStatusPostback()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a working copy by cloning, copying, or similar.
|
||||
*/
|
||||
public function createWorkingCopy(Builder $builder, $buildPath)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -20,16 +20,25 @@ use PHPCI\Model\Build\RemoteGitBuild;
|
|||
*/
|
||||
class BitbucketBuild extends RemoteGitBuild
|
||||
{
|
||||
/**
|
||||
* Get link to commit from another source (i.e. Github)
|
||||
*/
|
||||
public function getCommitLink()
|
||||
{
|
||||
return 'https://bitbucket.org/' . $this->getProject()->getReference() . '/commits/' . $this->getCommitId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to branch from another source (i.e. Github)
|
||||
*/
|
||||
public function getBranchLink()
|
||||
{
|
||||
return 'https://bitbucket.org/' . $this->getProject()->getReference() . '/src/?at=' . $this->getBranch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL to be used to clone this remote repository.
|
||||
*/
|
||||
protected function getCloneUrl()
|
||||
{
|
||||
$key = trim($this->getProject()->getGitKey());
|
||||
|
|
|
@ -19,16 +19,25 @@ use PHPCI\Model\Build\RemoteGitBuild;
|
|||
*/
|
||||
class GithubBuild extends RemoteGitBuild
|
||||
{
|
||||
/**
|
||||
* Get link to commit from another source (i.e. Github)
|
||||
*/
|
||||
public function getCommitLink()
|
||||
{
|
||||
return 'https://github.com/' . $this->getProject()->getReference() . '/commit/' . $this->getCommitId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to branch from another source (i.e. Github)
|
||||
*/
|
||||
public function getBranchLink()
|
||||
{
|
||||
return 'https://github.com/' . $this->getProject()->getReference() . '/tree/' . $this->getBranch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send status updates to any relevant third parties (i.e. Github)
|
||||
*/
|
||||
public function sendStatusPostback()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
|
@ -70,6 +79,9 @@ class GithubBuild extends RemoteGitBuild
|
|||
$http->request('POST', $url, json_encode($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL to be used to clone this remote repository.
|
||||
*/
|
||||
protected function getCloneUrl()
|
||||
{
|
||||
$key = trim($this->getProject()->getGitKey());
|
||||
|
|
|
@ -21,6 +21,9 @@ use Symfony\Component\Yaml\Parser as YamlParser;
|
|||
*/
|
||||
class LocalBuild extends Build
|
||||
{
|
||||
/**
|
||||
* Create a working copy by cloning, copying, or similar.
|
||||
*/
|
||||
public function createWorkingCopy(Builder $builder, $buildPath)
|
||||
{
|
||||
$reference = $this->getProject()->getReference();
|
||||
|
|
|
@ -21,8 +21,14 @@ use Symfony\Component\Yaml\Parser as YamlParser;
|
|||
*/
|
||||
abstract class RemoteGitBuild extends Build
|
||||
{
|
||||
/**
|
||||
* Get the URL to be used to clone this remote repository.
|
||||
*/
|
||||
abstract protected function getCloneUrl();
|
||||
|
||||
/**
|
||||
* Create a working copy by cloning, copying, or similar.
|
||||
*/
|
||||
public function createWorkingCopy(Builder $builder, $buildPath)
|
||||
{
|
||||
$yamlParser = new YamlParser();
|
||||
|
@ -51,11 +57,17 @@ abstract class RemoteGitBuild extends Build
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use an HTTP-based git clone.
|
||||
*/
|
||||
protected function cloneByHttp(Builder $builder, $to)
|
||||
{
|
||||
return $builder->executeCommand('git clone -b %s %s "%s"', $this->getBranch(), $this->getCloneUrl(), $to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use an SSH-based git clone.
|
||||
*/
|
||||
protected function cloneBySsh(Builder $builder, $to)
|
||||
{
|
||||
// Copy the project's keyfile to disk:
|
||||
|
|
|
@ -29,6 +29,9 @@ class Composer implements \PHPCI\Plugin
|
|||
$this->action = isset($options['action']) ? $options['action'] : 'update';
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes Composer and runs a specified command (e.g. install / update)
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$cmd = PHPCI_DIR . 'composer.phar --prefer-dist --working-dir="%s" %s';
|
||||
|
|
|
@ -46,6 +46,9 @@ class Mysql implements \PHPCI\Plugin
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to MySQL and runs a specified set of queries.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
|
|
|
@ -41,6 +41,9 @@ class Pgsql implements \PHPCI\Plugin
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to PgSQL and runs a specified set of queries.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
|
|
|
@ -28,10 +28,13 @@ class PhpCodeSniffer implements \PHPCI\Plugin
|
|||
$this->standard = isset($options['standard']) ? $options['standard'] : 'PSR2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs PHP Code Sniffer in a specified directory, to a specified standard.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$ignore = '';
|
||||
|
||||
|
||||
if (count($this->phpci->ignore)) {
|
||||
$ignore = ' --ignore=' . implode(',', $this->phpci->ignore);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ class PhpCpd implements \PHPCI\Plugin
|
|||
$this->standard = isset($options['standard']) ? $options['standard'] : 'PSR2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs PHP Copy/Paste Detector in a specified directory.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$ignore = '';
|
||||
|
|
|
@ -24,6 +24,9 @@ class PhpMessDetector implements \PHPCI\Plugin
|
|||
$this->phpci = $phpci;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs PHP Mess Detector in a specified directory.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$ignore = '';
|
||||
|
|
|
@ -24,6 +24,9 @@ class PhpSpec implements \PHPCI\Plugin
|
|||
$this->phpci = $phpci;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs PHP Spec tests.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$curdir = getcwd();
|
||||
|
|
|
@ -39,23 +39,26 @@ class PhpUnit implements \PHPCI\Plugin
|
|||
{
|
||||
$this->phpci = $phpci;
|
||||
|
||||
if(isset($options['directory'])) {
|
||||
if (isset($options['directory'])) {
|
||||
$this->directory = $options['directory'];
|
||||
}
|
||||
|
||||
if(isset($options['config'])) {
|
||||
if (isset($options['config'])) {
|
||||
$this->xmlConfigFile = $options['config'];
|
||||
}
|
||||
|
||||
if(isset($options['run_from'])) {
|
||||
if (isset($options['run_from'])) {
|
||||
$this->runFrom = $options['run_from'];
|
||||
}
|
||||
|
||||
if(isset($options['args'])) {
|
||||
if (isset($options['args'])) {
|
||||
$this->args = $options['args'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs PHP Unit tests in a specified directory, optionally using specified config file(s).
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$success = true;
|
||||
|
|
Loading…
Reference in a new issue