Gogs integration

This commit is contained in:
Simon Vieille 2016-12-05 00:58:11 +01:00
parent 64b0f60368
commit 32054ee565
14 changed files with 117 additions and 33 deletions

View file

@ -315,6 +315,7 @@ class ProjectController extends PHPCI\Controller
'github' => Lang::get('github'), 'github' => Lang::get('github'),
'bitbucket' => Lang::get('bitbucket'), 'bitbucket' => Lang::get('bitbucket'),
'gitlab' => Lang::get('gitlab'), 'gitlab' => Lang::get('gitlab'),
'gogs' => Lang::get('gogs'),
'remote' => Lang::get('remote'), 'remote' => Lang::get('remote'),
'local' => Lang::get('local'), 'local' => Lang::get('local'),
'hg' => Lang::get('hg'), 'hg' => Lang::get('hg'),
@ -322,7 +323,7 @@ class ProjectController extends PHPCI\Controller
); );
$field = Form\Element\Select::create('type', Lang::get('where_hosted'), true); $field = Form\Element\Select::create('type', Lang::get('where_hosted'), true);
$field->setPattern('^(github|bitbucket|gitlab|remote|local|hg|svn)'); $field->setPattern('^(github|bitbucket|gitlab|gogs|remote|local|hg|svn)');
$field->setOptions($options); $field->setOptions($options);
$field->setClass('form-control')->setContainerClass('form-group'); $field->setClass('form-control')->setContainerClass('form-group');
$form->addField($field); $form->addField($field);
@ -425,6 +426,10 @@ class ProjectController extends PHPCI\Controller
'regex' => '/^(git|https?):\/\//', 'regex' => '/^(git|https?):\/\//',
'message' => Lang::get('error_remote') 'message' => Lang::get('error_remote')
), ),
'gogs' => array(
'regex' => '/^(git|https?):\/\//',
'message' => Lang::get('error_remote')
),
'gitlab' => array( 'gitlab' => array(
'regex' => '`^(.*)@(.*):(.*)/(.*)\.git`', 'regex' => '`^(.*)@(.*):(.*)/(.*)\.git`',
'message' => Lang::get('error_gitlab') 'message' => Lang::get('error_gitlab')

View file

@ -1,32 +1,29 @@
<?php <?php
/** /**
* PHPCI - Continuous Integration for PHP * PHPCI - Continuous Integration for PHP.
* *
* @copyright Copyright 2014-2015, Block 8 Limited. * @copyright Copyright 2014-2015, Block 8 Limited
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md * @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
*
* @link https://www.phptesting.org/ * @link https://www.phptesting.org/
*/ */
namespace PHPCI\Controller; namespace PHPCI\Controller;
use b8; use b8;
use b8\Store; use b8\Store;
use Exception; use Exception;
use PHPCI\BuildFactory;
use PHPCI\Model\Project; use PHPCI\Model\Project;
use PHPCI\Service\BuildService; use PHPCI\Service\BuildService;
use PHPCI\Store\BuildStore; use PHPCI\Store\BuildStore;
use PHPCI\Store\ProjectStore; use PHPCI\Store\ProjectStore;
/** /**
* Webhook Controller - Processes webhook pings from BitBucket, Github, Gitlab, etc. * Webhook Controller - Processes webhook pings from BitBucket, Github, Gitlab, Gogs, etc.
* *
* @author Dan Cryer <dan@block8.co.uk> * @author Dan Cryer <dan@block8.co.uk>
* @author Sami Tikka <stikka@iki.fi> * @author Sami Tikka <stikka@iki.fi>
* @author Alex Russell <alex@clevercherry.com> * @author Alex Russell <alex@clevercherry.com>
* @author Guillaume Perréal <adirelle@gmail.com> * @author Guillaume Perréal <adirelle@gmail.com>
* @package PHPCI
* @subpackage Web
* *
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
*/ */
@ -58,9 +55,8 @@ class WebhookController extends \b8\Controller
} }
/** Handle the action, Ensuring to return a JsonResponse. /** Handle the action, Ensuring to return a JsonResponse.
*
* @param string $action * @param string $action
* @param mixed $actionParams * @param mixed $actionParams
* *
* @return \b8\Http\Response * @return \b8\Http\Response
*/ */
@ -78,6 +74,7 @@ class WebhookController extends \b8\Controller
$response->setResponseCode(500); $response->setResponseCode(500);
$response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage()));
} }
return $response; return $response;
} }
@ -87,19 +84,19 @@ class WebhookController extends \b8\Controller
public function bitbucket($projectId) public function bitbucket($projectId)
{ {
$project = $this->fetchProject($projectId, 'bitbucket'); $project = $this->fetchProject($projectId, 'bitbucket');
// Support both old services and new webhooks // Support both old services and new webhooks
if ($payload = $this->getParam('payload')) { if ($payload = $this->getParam('payload')) {
return $this->bitbucketService(json_decode($payload, true), $project); return $this->bitbucketService(json_decode($payload, true), $project);
} }
$payload = json_decode(file_get_contents("php://input"), true); $payload = json_decode(file_get_contents('php://input'), true);
if (empty($payload['push']['changes'])) { if (empty($payload['push']['changes'])) {
// Invalid event from bitbucket // Invalid event from bitbucket
return [ return [
'status' => 'failed', 'status' => 'failed',
'commits' => [] 'commits' => [],
]; ];
} }
@ -167,7 +164,7 @@ class WebhookController extends \b8\Controller
} }
/** /**
* Called by POSTing to /webhook/git/<project_id>?branch=<branch>&commit=<commit> * Called by POSTing to /webhook/git/<project_id>?branch=<branch>&commit=<commit>.
* *
* @param string $projectId * @param string $projectId
*/ */
@ -183,7 +180,7 @@ class WebhookController extends \b8\Controller
} }
/** /**
* Called by Github Webhooks: * Called by Github Webhooks:.
*/ */
public function github($projectId) public function github($projectId)
{ {
@ -216,8 +213,8 @@ class WebhookController extends \b8\Controller
/** /**
* Handle the payload when Github sends a commit webhook. * Handle the payload when Github sends a commit webhook.
* *
* @param Project $project * @param Project $project
* @param array $payload * @param array $payload
* @param b8\Http\Response\JsonResponse $response * @param b8\Http\Response\JsonResponse $response
* *
* @return b8\Http\Response\JsonResponse * @return b8\Http\Response\JsonResponse
@ -256,6 +253,7 @@ class WebhookController extends \b8\Controller
$results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage());
} }
} }
return array('status' => $status, 'commits' => $results); return array('status' => $status, 'commits' => $results);
} }
@ -264,6 +262,7 @@ class WebhookController extends \b8\Controller
$branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']); $branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']);
$committer = $payload['pusher']['email']; $committer = $payload['pusher']['email'];
$message = $payload['head_commit']['message']; $message = $payload['head_commit']['message'];
return $this->createBuild($project, $payload['after'], $branch, $committer, $message); return $this->createBuild($project, $payload['after'], $branch, $committer, $message);
} }
@ -274,7 +273,7 @@ class WebhookController extends \b8\Controller
* Handle the payload when Github sends a Pull Request webhook. * Handle the payload when Github sends a Pull Request webhook.
* *
* @param Project $project * @param Project $project
* @param array $payload * @param array $payload
*/ */
protected function githubPullRequest(Project $project, array $payload) protected function githubPullRequest(Project $project, array $payload)
{ {
@ -287,11 +286,11 @@ class WebhookController extends \b8\Controller
$token = \b8\Config::getInstance()->get('phpci.github.token'); $token = \b8\Config::getInstance()->get('phpci.github.token');
if (!empty($token)) { if (!empty($token)) {
$headers[] = 'Authorization: token ' . $token; $headers[] = 'Authorization: token '.$token;
} }
$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); $response = $http->get($url);
@ -336,13 +335,13 @@ class WebhookController extends \b8\Controller
} }
/** /**
* Called by Gitlab Webhooks: * Called by Gitlab Webhooks:.
*/ */
public function gitlab($projectId) public function gitlab($projectId)
{ {
$project = $this->fetchProject($projectId, 'gitlab'); $project = $this->fetchProject($projectId, 'gitlab');
$payloadString = file_get_contents("php://input"); $payloadString = file_get_contents('php://input');
$payload = json_decode($payloadString, true); $payload = json_decode($payloadString, true);
// build on merge request events // build on merge request events
@ -379,6 +378,71 @@ class WebhookController extends \b8\Controller
$results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage());
} }
} }
return array('status' => $status, 'commits' => $results);
}
return array('status' => 'ignored', 'message' => 'Unusable payload.');
}
/**
* Called by Gogs Webhooks:.
*/
public function gogs($projectId)
{
$project = $this->fetchProject($projectId, 'gogs');
switch ($_SERVER['CONTENT_TYPE']) {
case 'application/json':
$payload = json_decode(file_get_contents('php://input'), true);
break;
case 'application/x-www-form-urlencoded':
$payload = json_decode($this->getParam('payload'), true);
break;
default:
return array('status' => 'failed', 'error' => 'Content type not supported.', 'responseCode' => 401);
}
// Handle Push web hooks:
if (array_key_exists('commits', $payload)) {
return $this->gogsCommitRequest($project, $payload);
}
return array('status' => 'ignored', 'message' => 'Unusable payload.');
}
/**
* Handle the payload when Gogs sends a commit webhook.
*
* @param Project $project
* @param array $payload
* @param b8\Http\Response\JsonResponse $response
*
* @return b8\Http\Response\JsonResponse
*/
protected function gogsCommitRequest(Project $project, array $payload)
{
if (isset($payload['commits']) && is_array($payload['commits'])) {
// If we have a list of commits, then add them all as builds to be tested:
$results = array();
$status = 'failed';
foreach ($payload['commits'] as $commit) {
try {
$branch = str_replace('refs/heads/', '', $payload['ref']);
$committer = $commit['author']['email'];
$results[$commit['id']] = $this->createBuild(
$project,
$commit['id'],
$branch,
$committer,
$commit['message']
);
$status = 'ok';
} catch (Exception $ex) {
$results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage());
}
}
return array('status' => $status, 'commits' => $results); return array('status' => $status, 'commits' => $results);
} }
@ -389,11 +453,11 @@ class WebhookController extends \b8\Controller
* Wrapper for creating a new build. * Wrapper for creating a new build.
* *
* @param Project $project * @param Project $project
* @param string $commitId * @param string $commitId
* @param string $branch * @param string $branch
* @param string $committer * @param string $committer
* @param string $commitMessage * @param string $commitMessage
* @param array $extra * @param array $extra
* *
* @return array * @return array
* *
@ -413,7 +477,7 @@ class WebhookController extends \b8\Controller
if ($builds['count']) { if ($builds['count']) {
return array( return array(
'status' => 'ignored', 'status' => 'ignored',
'message' => sprintf('Duplicate of build #%d', $builds['items'][0]->getId()) 'message' => sprintf('Duplicate of build #%d', $builds['items'][0]->getId()),
); );
} }
@ -426,26 +490,26 @@ class WebhookController extends \b8\Controller
/** /**
* Fetch a project and check its type. * Fetch a project and check its type.
* *
* @param int $projectId * @param int $projectId
* @param array|string $expectedType * @param array|string $expectedType
* *
* @return Project * @return Project
* *
* @throws Exception If the project does not exist or is not of the expected type. * @throws Exception If the project does not exist or is not of the expected type
*/ */
protected function fetchProject($projectId, $expectedType) protected function fetchProject($projectId, $expectedType)
{ {
$project = $this->projectStore->getById($projectId); $project = $this->projectStore->getById($projectId);
if (empty($projectId)) { if (empty($projectId)) {
throw new Exception('Project does not exist: ' . $projectId); throw new Exception('Project does not exist: '.$projectId);
} }
if (is_array($expectedType) if (is_array($expectedType)
? !in_array($project->getType(), $expectedType) ? !in_array($project->getType(), $expectedType)
: $project->getType() !== $expectedType : $project->getType() !== $expectedType
) { ) {
throw new Exception('Wrong project type: ' . $project->getType()); throw new Exception('Wrong project type: '.$project->getType());
} }
return $project; return $project;

View file

@ -98,6 +98,7 @@ i din foretrukne hosting-platform.',
'github' => 'GitHub', 'github' => 'GitHub',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'gogs' => 'Gogs',
'remote' => 'Ekstern URL', 'remote' => 'Ekstern URL',
'local' => 'Lokalt filsystem', 'local' => 'Lokalt filsystem',
'hg' => 'Mercurial', 'hg' => 'Mercurial',

View file

@ -99,6 +99,7 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab
'github' => 'GitHub', 'github' => 'GitHub',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'gogs' => 'Gogs',
'remote' => 'Externe URL', 'remote' => 'Externe URL',
'local' => 'Lokaler Pfad', 'local' => 'Lokaler Pfad',
'hg' => 'Mercurial', 'hg' => 'Mercurial',

View file

@ -99,6 +99,7 @@ PHPCI',
'github' => 'GitHub', 'github' => 'GitHub',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'gogs' => 'Gogs',
'remote' => 'Απομακρυσμένη διεύθυνση URL', 'remote' => 'Απομακρυσμένη διεύθυνση URL',
'local' => 'Τοπική Διαδρομή', 'local' => 'Τοπική Διαδρομή',
'hg' => 'Ευμετάβλητο', 'hg' => 'Ευμετάβλητο',

View file

@ -99,6 +99,7 @@ PHPCI',
'github' => 'GitHub', 'github' => 'GitHub',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'gogs' => 'Gogs',
'remote' => 'Remote URL', 'remote' => 'Remote URL',
'local' => 'Local Path', 'local' => 'Local Path',
'hg' => 'Mercurial', 'hg' => 'Mercurial',

View file

@ -99,6 +99,7 @@ PHPCI',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'remote' => 'URL Remota', 'remote' => 'URL Remota',
'gogs' => 'Gogs',
'local' => 'Path local', 'local' => 'Path local',
'hg' => 'Mercurial', 'hg' => 'Mercurial',
'svn' => 'Subversion', 'svn' => 'Subversion',

View file

@ -99,6 +99,7 @@ PHPCI',
'github' => 'GitHub', 'github' => 'GitHub',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'gogs' => 'Gogs',
'remote' => 'URL distante', 'remote' => 'URL distante',
'local' => 'Chemin local', 'local' => 'Chemin local',
'hg' => 'Mercurial', 'hg' => 'Mercurial',

View file

@ -99,6 +99,7 @@ PHPCI',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'remote' => 'URL Remoto', 'remote' => 'URL Remoto',
'gogs' => 'Gogs',
'local' => 'Percorso Locale', 'local' => 'Percorso Locale',
'hg' => 'Mercurial', 'hg' => 'Mercurial',

View file

@ -99,6 +99,7 @@ van je gekozen source code hosting platform',
'github' => 'GitHub', 'github' => 'GitHub',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'gogs' => 'Gogs',
'remote' => 'Externe URL', 'remote' => 'Externe URL',
'local' => 'Lokaal pad', 'local' => 'Lokaal pad',
'hg' => 'Mercurial', 'hg' => 'Mercurial',

View file

@ -99,6 +99,7 @@ od wybranego kodu źródłowego platformy hostingowej.',
'github' => 'GitHub', 'github' => 'GitHub',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'gogs' => 'Gogs',
'remote' => 'Zdalny URL ', 'remote' => 'Zdalny URL ',
'local' => 'Lokalna Ścieżka ', 'local' => 'Lokalna Ścieżka ',
'hg' => 'Mercurial', 'hg' => 'Mercurial',

View file

@ -99,6 +99,7 @@ PHPCI',
'remote' => 'Внешний URL', 'remote' => 'Внешний URL',
'local' => 'Локальный путь', 'local' => 'Локальный путь',
'hg' => 'Mercurial', 'hg' => 'Mercurial',
'gogs' => 'Gogs',
'svn' => 'Subversion', 'svn' => 'Subversion',
'where_hosted' => 'Расположение проекта', 'where_hosted' => 'Расположение проекта',

View file

@ -99,6 +99,7 @@ PHPCI',
'bitbucket' => 'Bitbucket', 'bitbucket' => 'Bitbucket',
'gitlab' => 'GitLab', 'gitlab' => 'GitLab',
'remote' => 'Віддалений URL', 'remote' => 'Віддалений URL',
'gogs' => 'Gogs',
'local' => 'Локальний шлях', 'local' => 'Локальний шлях',
'hg' => 'Mercurial', 'hg' => 'Mercurial',

View file

@ -87,6 +87,10 @@
Lang::out('webhooks_help_gitlab'); Lang::out('webhooks_help_gitlab');
break; break;
case 'gogs':
$url = PHPCI_URL. 'webhook/gogs/' . $project->getId();
break;
case 'bitbucket': case 'bitbucket':
$url = PHPCI_URL . 'webhook/bitbucket/' . $project->getId(); $url = PHPCI_URL . 'webhook/bitbucket/' . $project->getId();
Lang::out('webhooks_help_bitbucket', $project->getReference()); Lang::out('webhooks_help_bitbucket', $project->getReference());