From 32054ee565778a5bb815bf8bba4f5329b376d26f Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Mon, 5 Dec 2016 00:58:11 +0100 Subject: [PATCH] Gogs integration --- PHPCI/Controller/ProjectController.php | 7 +- PHPCI/Controller/WebhookController.php | 128 ++++++++++++++++++------- PHPCI/Languages/lang.da.php | 1 + PHPCI/Languages/lang.de.php | 1 + PHPCI/Languages/lang.el.php | 1 + PHPCI/Languages/lang.en.php | 1 + PHPCI/Languages/lang.es.php | 1 + PHPCI/Languages/lang.fr.php | 1 + PHPCI/Languages/lang.it.php | 1 + PHPCI/Languages/lang.nl.php | 1 + PHPCI/Languages/lang.pl.php | 1 + PHPCI/Languages/lang.ru.php | 1 + PHPCI/Languages/lang.uk.php | 1 + PHPCI/View/Project/view.phtml | 4 + 14 files changed, 117 insertions(+), 33 deletions(-) diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index 72be46e5..78be73ec 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -315,6 +315,7 @@ class ProjectController extends PHPCI\Controller 'github' => Lang::get('github'), 'bitbucket' => Lang::get('bitbucket'), 'gitlab' => Lang::get('gitlab'), + 'gogs' => Lang::get('gogs'), 'remote' => Lang::get('remote'), 'local' => Lang::get('local'), '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->setPattern('^(github|bitbucket|gitlab|remote|local|hg|svn)'); + $field->setPattern('^(github|bitbucket|gitlab|gogs|remote|local|hg|svn)'); $field->setOptions($options); $field->setClass('form-control')->setContainerClass('form-group'); $form->addField($field); @@ -425,6 +426,10 @@ class ProjectController extends PHPCI\Controller 'regex' => '/^(git|https?):\/\//', 'message' => Lang::get('error_remote') ), + 'gogs' => array( + 'regex' => '/^(git|https?):\/\//', + 'message' => Lang::get('error_remote') + ), 'gitlab' => array( 'regex' => '`^(.*)@(.*):(.*)/(.*)\.git`', 'message' => Lang::get('error_gitlab') diff --git a/PHPCI/Controller/WebhookController.php b/PHPCI/Controller/WebhookController.php index 4b444d03..bdc69c64 100644 --- a/PHPCI/Controller/WebhookController.php +++ b/PHPCI/Controller/WebhookController.php @@ -1,32 +1,29 @@ * @author Sami Tikka * @author Alex Russell * @author Guillaume Perréal - * @package PHPCI - * @subpackage Web * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ @@ -58,9 +55,8 @@ class WebhookController extends \b8\Controller } /** Handle the action, Ensuring to return a JsonResponse. - * * @param string $action - * @param mixed $actionParams + * @param mixed $actionParams * * @return \b8\Http\Response */ @@ -78,6 +74,7 @@ class WebhookController extends \b8\Controller $response->setResponseCode(500); $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); } + return $response; } @@ -87,19 +84,19 @@ class WebhookController extends \b8\Controller public function bitbucket($projectId) { $project = $this->fetchProject($projectId, 'bitbucket'); - + // Support both old services and new webhooks if ($payload = $this->getParam('payload')) { 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'])) { // Invalid event from bitbucket return [ 'status' => 'failed', - 'commits' => [] + 'commits' => [], ]; } @@ -167,7 +164,7 @@ class WebhookController extends \b8\Controller } /** - * Called by POSTing to /webhook/git/?branch=&commit= + * Called by POSTing to /webhook/git/?branch=&commit=. * * @param string $projectId */ @@ -183,7 +180,7 @@ class WebhookController extends \b8\Controller } /** - * Called by Github Webhooks: + * Called by Github Webhooks:. */ public function github($projectId) { @@ -216,8 +213,8 @@ class WebhookController extends \b8\Controller /** * Handle the payload when Github sends a commit webhook. * - * @param Project $project - * @param array $payload + * @param Project $project + * @param array $payload * @param b8\Http\Response\JsonResponse $response * * @return b8\Http\Response\JsonResponse @@ -256,6 +253,7 @@ class WebhookController extends \b8\Controller $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); } } + return array('status' => $status, 'commits' => $results); } @@ -264,6 +262,7 @@ class WebhookController extends \b8\Controller $branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']); $committer = $payload['pusher']['email']; $message = $payload['head_commit']['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. * * @param Project $project - * @param array $payload + * @param 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'); if (!empty($token)) { - $headers[] = 'Authorization: token ' . $token; + $headers[] = 'Authorization: token '.$token; } - $url = $payload['pull_request']['commits_url']; - $http = new \b8\HttpClient(); + $url = $payload['pull_request']['commits_url']; + $http = new \b8\HttpClient(); $http->setHeaders($headers); $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) { $project = $this->fetchProject($projectId, 'gitlab'); - $payloadString = file_get_contents("php://input"); + $payloadString = file_get_contents('php://input'); $payload = json_decode($payloadString, true); // build on merge request events @@ -379,6 +378,71 @@ class WebhookController extends \b8\Controller $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); } @@ -389,11 +453,11 @@ class WebhookController extends \b8\Controller * Wrapper for creating a new build. * * @param Project $project - * @param string $commitId - * @param string $branch - * @param string $committer - * @param string $commitMessage - * @param array $extra + * @param string $commitId + * @param string $branch + * @param string $committer + * @param string $commitMessage + * @param array $extra * * @return array * @@ -413,7 +477,7 @@ class WebhookController extends \b8\Controller if ($builds['count']) { return array( '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. * - * @param int $projectId + * @param int $projectId * @param array|string $expectedType * * @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) { $project = $this->projectStore->getById($projectId); if (empty($projectId)) { - throw new Exception('Project does not exist: ' . $projectId); + throw new Exception('Project does not exist: '.$projectId); } if (is_array($expectedType) ? !in_array($project->getType(), $expectedType) : $project->getType() !== $expectedType ) { - throw new Exception('Wrong project type: ' . $project->getType()); + throw new Exception('Wrong project type: '.$project->getType()); } return $project; diff --git a/PHPCI/Languages/lang.da.php b/PHPCI/Languages/lang.da.php index d7a0df59..a594cec2 100644 --- a/PHPCI/Languages/lang.da.php +++ b/PHPCI/Languages/lang.da.php @@ -98,6 +98,7 @@ i din foretrukne hosting-platform.', 'github' => 'GitHub', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', + 'gogs' => 'Gogs', 'remote' => 'Ekstern URL', 'local' => 'Lokalt filsystem', 'hg' => 'Mercurial', diff --git a/PHPCI/Languages/lang.de.php b/PHPCI/Languages/lang.de.php index 8e5bb3b2..6d2633d6 100644 --- a/PHPCI/Languages/lang.de.php +++ b/PHPCI/Languages/lang.de.php @@ -99,6 +99,7 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'github' => 'GitHub', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', + 'gogs' => 'Gogs', 'remote' => 'Externe URL', 'local' => 'Lokaler Pfad', 'hg' => 'Mercurial', diff --git a/PHPCI/Languages/lang.el.php b/PHPCI/Languages/lang.el.php index 45ee4bee..a8225976 100644 --- a/PHPCI/Languages/lang.el.php +++ b/PHPCI/Languages/lang.el.php @@ -99,6 +99,7 @@ PHPCI', 'github' => 'GitHub', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', + 'gogs' => 'Gogs', 'remote' => 'Απομακρυσμένη διεύθυνση URL', 'local' => 'Τοπική Διαδρομή', 'hg' => 'Ευμετάβλητο', diff --git a/PHPCI/Languages/lang.en.php b/PHPCI/Languages/lang.en.php index 63df75d2..0b88db84 100644 --- a/PHPCI/Languages/lang.en.php +++ b/PHPCI/Languages/lang.en.php @@ -99,6 +99,7 @@ PHPCI', 'github' => 'GitHub', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', + 'gogs' => 'Gogs', 'remote' => 'Remote URL', 'local' => 'Local Path', 'hg' => 'Mercurial', diff --git a/PHPCI/Languages/lang.es.php b/PHPCI/Languages/lang.es.php index 1b7b33f7..d6d7348f 100644 --- a/PHPCI/Languages/lang.es.php +++ b/PHPCI/Languages/lang.es.php @@ -99,6 +99,7 @@ PHPCI', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', 'remote' => 'URL Remota', + 'gogs' => 'Gogs', 'local' => 'Path local', 'hg' => 'Mercurial', 'svn' => 'Subversion', diff --git a/PHPCI/Languages/lang.fr.php b/PHPCI/Languages/lang.fr.php index a0f2cab8..5f54b6b1 100644 --- a/PHPCI/Languages/lang.fr.php +++ b/PHPCI/Languages/lang.fr.php @@ -99,6 +99,7 @@ PHPCI', 'github' => 'GitHub', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', + 'gogs' => 'Gogs', 'remote' => 'URL distante', 'local' => 'Chemin local', 'hg' => 'Mercurial', diff --git a/PHPCI/Languages/lang.it.php b/PHPCI/Languages/lang.it.php index d254fbcd..bb3cca6d 100644 --- a/PHPCI/Languages/lang.it.php +++ b/PHPCI/Languages/lang.it.php @@ -99,6 +99,7 @@ PHPCI', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', 'remote' => 'URL Remoto', + 'gogs' => 'Gogs', 'local' => 'Percorso Locale', 'hg' => 'Mercurial', diff --git a/PHPCI/Languages/lang.nl.php b/PHPCI/Languages/lang.nl.php index 96d9f5d5..26ee6e9d 100644 --- a/PHPCI/Languages/lang.nl.php +++ b/PHPCI/Languages/lang.nl.php @@ -99,6 +99,7 @@ van je gekozen source code hosting platform', 'github' => 'GitHub', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', + 'gogs' => 'Gogs', 'remote' => 'Externe URL', 'local' => 'Lokaal pad', 'hg' => 'Mercurial', diff --git a/PHPCI/Languages/lang.pl.php b/PHPCI/Languages/lang.pl.php index e1d3c3bf..cc02b1cc 100644 --- a/PHPCI/Languages/lang.pl.php +++ b/PHPCI/Languages/lang.pl.php @@ -99,6 +99,7 @@ od wybranego kodu źródłowego platformy hostingowej.', 'github' => 'GitHub', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', + 'gogs' => 'Gogs', 'remote' => 'Zdalny URL ', 'local' => 'Lokalna Ścieżka ', 'hg' => 'Mercurial', diff --git a/PHPCI/Languages/lang.ru.php b/PHPCI/Languages/lang.ru.php index 0a7acff2..8a3e7283 100644 --- a/PHPCI/Languages/lang.ru.php +++ b/PHPCI/Languages/lang.ru.php @@ -99,6 +99,7 @@ PHPCI', 'remote' => 'Внешний URL', 'local' => 'Локальный путь', 'hg' => 'Mercurial', + 'gogs' => 'Gogs', 'svn' => 'Subversion', 'where_hosted' => 'Расположение проекта', diff --git a/PHPCI/Languages/lang.uk.php b/PHPCI/Languages/lang.uk.php index 54ced220..554c3cd2 100644 --- a/PHPCI/Languages/lang.uk.php +++ b/PHPCI/Languages/lang.uk.php @@ -99,6 +99,7 @@ PHPCI', 'bitbucket' => 'Bitbucket', 'gitlab' => 'GitLab', 'remote' => 'Віддалений URL', + 'gogs' => 'Gogs', 'local' => 'Локальний шлях', 'hg' => 'Mercurial', diff --git a/PHPCI/View/Project/view.phtml b/PHPCI/View/Project/view.phtml index 79b7ef0e..14a55b11 100644 --- a/PHPCI/View/Project/view.phtml +++ b/PHPCI/View/Project/view.phtml @@ -87,6 +87,10 @@ Lang::out('webhooks_help_gitlab'); break; + case 'gogs': + $url = PHPCI_URL. 'webhook/gogs/' . $project->getId(); + break; + case 'bitbucket': $url = PHPCI_URL . 'webhook/bitbucket/' . $project->getId(); Lang::out('webhooks_help_bitbucket', $project->getReference());