Merge pull request #6 from Block8/feature/github_integration
Merging Github integration. Drop down select repositories, Github commit statuses.
This commit is contained in:
commit
c9b17e3534
|
@ -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));
|
||||
|
|
|
@ -36,7 +36,8 @@ class GithubController extends b8\Controller
|
|||
|
||||
try
|
||||
{
|
||||
$this->_buildStore->save($build);
|
||||
$build = $this->_buildStore->save($build);
|
||||
$build->sendStatusPostback();
|
||||
}
|
||||
catch(\Exception $ex)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ class SessionController extends b8\Controller
|
|||
public function logout()
|
||||
{
|
||||
unset($_SESSION['user_id']);
|
||||
unset($_SESSION['github_token']);
|
||||
header('Location: /');
|
||||
die;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -23,6 +23,20 @@
|
|||
|
||||
<script>
|
||||
|
||||
<?php
|
||||
$gh = \b8\Registry::getInstance()->get('github_app', null);
|
||||
|
||||
if($gh)
|
||||
{
|
||||
print 'window.github_app_id = ' . json_encode($gh['id']) . ';' . PHP_EOL;
|
||||
}
|
||||
|
||||
if(!empty($token))
|
||||
{
|
||||
print 'window.github_token = ' . json_encode($token) . ';' . PHP_EOL;
|
||||
}
|
||||
?>
|
||||
|
||||
$(document).ready(function()
|
||||
{
|
||||
$('#element-reference').change(function()
|
||||
|
@ -39,13 +53,53 @@ $(document).ready(function()
|
|||
'bb_anon': /https\:\/\/bitbucket.org\/([a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+)(\.git)?/
|
||||
};
|
||||
|
||||
|
||||
for(var i in acceptable) {
|
||||
if(val.match(acceptable[i])) {
|
||||
el.val(val.replace(acceptable[i], '$1'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#element-type').change(function()
|
||||
{
|
||||
if(!window.github_app_id || $(this).val() != 'github' || window.github_token) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show sign in with Github button.
|
||||
var el = $('#element-reference');
|
||||
var rtn = <?= json_encode((empty($_SERVER['HTTPS']) ? 'http' : 'https') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); ?>;
|
||||
var url = 'https://github.com/login/oauth/authorize?client_id=' + window.github_app_id + '&scope=repo&redirect_uri=' + rtn;
|
||||
var btn = $('<a>').addClass('btn btn-inverse').text('Sign in with Github').attr('href', url);
|
||||
|
||||
el.after(btn);
|
||||
el.remove();
|
||||
});
|
||||
|
||||
$('#element-github').change(function()
|
||||
{
|
||||
var val = $('#element-github').val();
|
||||
|
||||
if(val != 'choose') {
|
||||
$('#element-type').val('github');
|
||||
$('#element-reference').val(val);
|
||||
|
||||
$('label[for=element-reference]').hide();
|
||||
$('label[for=element-type]').hide();
|
||||
$('#element-reference').hide();
|
||||
$('#element-type').hide();
|
||||
$('#element-token').val(window.github_token);
|
||||
$('#element-title').val(val);
|
||||
}
|
||||
else {
|
||||
$('label[for=element-reference]').show();
|
||||
$('label[for=element-type]').show();
|
||||
$('#element-reference').show();
|
||||
$('#element-type').show();
|
||||
$('#element-reference').val('');
|
||||
$('#element-token').val('');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
17
install.php
17
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', "<?php
|
||||
$str = "<?php
|
||||
|
||||
define('PHPCI_DB_HOST', '{$dbHost}');
|
||||
|
||||
|
@ -19,7 +22,17 @@ b8\Database::setDetails('{$dbName}', '{$dbUser}', '{$dbPass}');
|
|||
b8\Database::setWriteServers(array('{$dbHost}'));
|
||||
b8\Database::setReadServers(array('{$dbHost}'));
|
||||
|
||||
");
|
||||
\$registry = b8\Registry::getInstance();
|
||||
\$registry->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'))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue