diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 2f1b870e..2d9607ff 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -29,6 +29,7 @@ class Builder $this->build->setStatus(1); $this->build->setStarted(new \DateTime()); $this->build = $this->store->save($this->build); + $this->build->sendStatusPostback(); if($this->setupBuild()) { @@ -61,6 +62,7 @@ class Builder $this->removeBuild(); + $this->build->sendStatusPostback(); $this->build->setFinished(new \DateTime()); $this->build->setLog($this->log); $this->build->setPlugins(json_encode($this->plugins)); diff --git a/PHPCI/Controller/GithubController.php b/PHPCI/Controller/GithubController.php index bd3c478d..7e1626b9 100644 --- a/PHPCI/Controller/GithubController.php +++ b/PHPCI/Controller/GithubController.php @@ -36,7 +36,8 @@ class GithubController extends b8\Controller try { - $this->_buildStore->save($build); + $build = $this->_buildStore->save($build); + $build->sendStatusPostback(); } catch(\Exception $ex) { diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index fecb424b..d424f376 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -98,18 +98,34 @@ class ProjectController extends b8\Controller $pub = file_get_contents($id . '.pub'); $prv = file_get_contents($id); - $values = array('key' => $prv); + $values = array('key' => $prv, 'pubkey' => $pub, 'token' => $_SESSION['github_token']); } $form = $this->projectForm($values); if($method != 'POST' || ($method == 'POST' && !$form->validate())) { + $gh = \b8\Registry::getInstance()->get('github_app'); + $code = $this->getParam('code', null); + + if(!is_null($code)) + { + $http = new \b8\HttpClient(); + $resp = $http->post('https://github.com/login/oauth/access_token', array('client_id' => $gh['id'], 'client_secret' => $gh['secret'], 'code' => $code)); + + if($resp['success']) + { + parse_str($resp['body'], $resp); + $_SESSION['github_token'] = $resp['access_token']; + } + } + $view = new b8\View('ProjectForm'); $view->type = 'add'; $view->project = null; $view->form = $form; $view->key = $pub; + $view->token = $_SESSION['github_token'] ? $_SESSION['github_token'] : null; return $view->render(); } @@ -175,20 +191,26 @@ class ProjectController extends b8\Controller $form->setMethod('POST'); $form->setAction('/project/' . $type); $form->addField(new Form\Element\Csrf('csrf')); - - $field = new Form\Element\Text('title'); - $field->setRequired(true); - $field->setLabel('Project Title'); - $field->setClass('span4'); - $form->addField($field); + $form->addField(new Form\Element\Hidden('token')); + $form->addField(new Form\Element\Hidden('pubkey')); $field = new Form\Element\Select('type'); $field->setRequired(true); - $field->setOptions(array('github' => 'Github', 'bitbucket' => 'Bitbucket', 'local' => 'Local Path')); + $field->setPattern('^(github|bitbucket|local)'); + $field->setOptions(array('choose' => 'Select repository type...', 'github' => 'Github', 'bitbucket' => 'Bitbucket', 'local' => 'Local Path')); $field->setLabel('Where is your project hosted?'); $field->setClass('span4'); $form->addField($field); + if(isset($_SESSION['github_token'])) + { + $field = new Form\Element\Select('github'); + $field->setLabel('Choose a Github repository:'); + $field->setClass('span4'); + $field->setOptions($this->getGithubRepositories()); + $form->addField($field); + } + $field = new Form\Element\Text('reference'); $field->setRequired(true); $field->setPattern('[a-zA-Z0-9_\-\/]+'); @@ -196,6 +218,12 @@ class ProjectController extends b8\Controller $field->setClass('span4'); $form->addField($field); + $field = new Form\Element\Text('title'); + $field->setRequired(true); + $field->setLabel('Project Title'); + $field->setClass('span4'); + $form->addField($field); + $field = new Form\Element\TextArea('key'); $field->setRequired(false); $field->setLabel('Private key to use to access repository (leave blank for local and/or anonymous remotes)'); @@ -211,4 +239,22 @@ class ProjectController extends b8\Controller $form->setValues($values); return $form; } + + protected function getGithubRepositories() + { + $http = new \b8\HttpClient(); + $res = $http->get('https://api.github.com/user/repos', array('type' => 'all', 'access_token' => $_SESSION['github_token'])); + + $rtn = array(); + $rtn['choose'] = 'Select a repository...'; + if($res['success']) + { + foreach($res['body'] as $repo) + { + $rtn[$repo['full_name']] = $repo['full_name']; + } + } + + return $rtn; + } } \ No newline at end of file diff --git a/PHPCI/Controller/SessionController.php b/PHPCI/Controller/SessionController.php index 0551dd4e..bd1bfc1a 100644 --- a/PHPCI/Controller/SessionController.php +++ b/PHPCI/Controller/SessionController.php @@ -53,6 +53,7 @@ class SessionController extends b8\Controller public function logout() { unset($_SESSION['user_id']); + unset($_SESSION['github_token']); header('Location: /'); die; } diff --git a/PHPCI/Model/Base/ProjectBase.php b/PHPCI/Model/Base/ProjectBase.php index 451871e5..e7a2c915 100644 --- a/PHPCI/Model/Base/ProjectBase.php +++ b/PHPCI/Model/Base/ProjectBase.php @@ -21,6 +21,7 @@ class ProjectBase extends Model 'reference' => null, 'git_key' => null, 'type' => null, + 'token' => null, ); protected $_getters = array( 'id' => 'getId', @@ -28,6 +29,7 @@ class ProjectBase extends Model 'reference' => 'getReference', 'git_key' => 'getGitKey', 'type' => 'getType', + 'token' => 'getToken', ); @@ -38,6 +40,7 @@ class ProjectBase extends Model 'reference' => 'setReference', 'git_key' => 'setGitKey', 'type' => 'setType', + 'token' => 'setToken', ); public $columns = array( @@ -80,6 +83,14 @@ class ProjectBase extends Model + ), + 'token' => array( + 'type' => 'varchar', + 'length' => '50', + 'nullable' => true, + + + ), ); public $indexes = array( @@ -130,6 +141,14 @@ class ProjectBase extends Model return $rtn; } + public function getToken() + { + $rtn = $this->_data['token']; + + + return $rtn; + } + public function setId($value) @@ -202,6 +221,20 @@ class ProjectBase extends Model $this->_setModified('type'); } + public function setToken($value) + { + + $this->_validateString('Token', $value); + if($this->_data['token'] == $value) + { + return; + } + + $this->_data['token'] = $value; + + $this->_setModified('token'); + } + diff --git a/PHPCI/Model/Build.php b/PHPCI/Model/Build.php index 2ce4bb35..56b14010 100644 --- a/PHPCI/Model/Build.php +++ b/PHPCI/Model/Build.php @@ -33,4 +33,41 @@ class Build extends BuildBase return 'https://github.com/' . $this->getProject()->getReference() . '/tree/' . $this->getBranch(); } } + + public function sendStatusPostback() + { + $project = $this->getProject(); + + if($project->getType() == 'github' && $project->getToken()) + { + $url = 'https://api.github.com/repos/'.$project->getReference().'/statuses/'.$this->getCommitId(); + $http = new \b8\HttpClient(); + + switch($this->getStatus()) + { + case 0: + case 1: + $status = 'pending'; + break; + + case 2: + $status = 'success'; + break; + + case 3: + $status = 'failure'; + break; + + default: + $status = 'error'; + break; + } + + $params = array( 'state' => $status, + 'target_url' => \b8\Registry::getInstance()->get('install_url') . '/build/view/' . $this->getId()); + + $http->setHeaders(array('Authorization: token ' . $project->getToken())); + $http->request('POST', $url, json_encode($params)); + } + } } diff --git a/PHPCI/Plugin/Composer.php b/PHPCI/Plugin/Composer.php index 0d470db4..ac73f7de 100644 --- a/PHPCI/Plugin/Composer.php +++ b/PHPCI/Plugin/Composer.php @@ -17,6 +17,6 @@ class Composer implements \PHPCI\Plugin public function execute() { - return $this->phpci->executeCommand(PHPCI_DIR . 'composer.phar --working-dir=' . $this->directory . ' ' . $this->action); + return $this->phpci->executeCommand(PHPCI_DIR . 'composer.phar --prefer-dist --working-dir=' . $this->directory . ' ' . $this->action); } } \ No newline at end of file diff --git a/PHPCI/View/ProjectForm.phtml b/PHPCI/View/ProjectForm.phtml index d0da4061..59342ae0 100644 --- a/PHPCI/View/ProjectForm.phtml +++ b/PHPCI/View/ProjectForm.phtml @@ -23,6 +23,20 @@ \ No newline at end of file diff --git a/install.php b/install.php index 96a611ae..52da6899 100644 --- a/install.php +++ b/install.php @@ -7,11 +7,14 @@ $dbHost = ask('Enter your MySQL host: '); $dbName = ask('Enter the database name PHPCI should use: '); $dbUser = ask('Enter your MySQL username: '); $dbPass = ask('Enter your MySQL password: ', true); +$ciUrl = ask('Your PHPCI URL (without trailing slash): ', true); +$ghId = ask('(Optional) Github Application ID: ', true); +$ghSecret = ask('(Optional) Github Application Secret: ', true); $cmd = 'mysql -u' . $dbUser . (!empty($dbPass) ? ' -p' . $dbPass : '') . ' -h' . $dbHost . ' -e "CREATE DATABASE IF NOT EXISTS ' . $dbName . '"'; shell_exec($cmd); -file_put_contents('./config.php', "set('install_url', '{$ciUrl}'); +"; + +if(!empty($ghId) && !empty($ghSecret)) +{ + $str .= PHP_EOL . "\$registry->set('github_app', array('id' => '{$ghId}', 'secret' => '{$ghSecret}'));" . PHP_EOL; +} + + +file_put_contents('./config.php', $str); if(!file_exists('./composer.phar')) { diff --git a/phpci.yml b/phpci.yml index d252d83a..d70e867b 100644 --- a/phpci.yml +++ b/phpci.yml @@ -1,7 +1,7 @@ build_settings: - verbose: false - ignore: - - "vendor" + verbose: false + ignore: + - "vendor" setup: composer: