Browse Source

Backport support for gitlab, GH:Enterprise and others from Toran Proxy, fixes #417, fixes #404, fixes #394

Jordi Boggiano 10 years ago
parent
commit
7050279ea7

+ 18 - 25
src/Packagist/WebBundle/Controller/ApiController.php

@@ -86,41 +86,34 @@ class ApiController extends Controller
     }
 
     /**
+     * @Route("/api/update-package", name="generic_postreceive", defaults={"_format" = "json"})
      * @Route("/api/github", name="github_postreceive", defaults={"_format" = "json"})
-     * @Method({"POST"})
-     */
-    public function githubPostReceive(Request $request)
-    {
-        // parse the GitHub payload
-        $payload = json_decode($request->request->get('payload'), true);
-
-        if (!$payload || !isset($payload['repository']['url'])) {
-            return new Response(json_encode(array('status' => 'error', 'message' => 'Missing or invalid payload',)), 406);
-        }
-
-        $urlRegex = '{^(?:https?://|git://|git@)?(?P<host>github\.com)[:/](?P<path>[\w.-]+/[\w.-]+?)(?:\.git)?$}';
-        $repoUrl = $payload['repository']['url'];
-
-        return $this->receivePost($request, $repoUrl, $urlRegex);
-    }
-
-    /**
      * @Route("/api/bitbucket", name="bitbucket_postreceive", defaults={"_format" = "json"})
      * @Method({"POST"})
      */
-    public function bitbucketPostReceive(Request $request)
+    public function updatePackageAction(Request $request)
     {
-        // decode Bitbucket's POST payload
+        // parse the payload
         $payload = json_decode($request->request->get('payload'), true);
+        if (!$payload && $request->headers->get('Content-Type') === 'application/json') {
+            $payload = json_decode($request->getContent(), true);
+        }
 
-        if (!$payload || !isset($payload['canon_url']) || !isset($payload['repository']['absolute_url'])) {
-            return new Response(json_encode(array('status' => 'error', 'message' => 'Missing or invalid payload',)), 406);
+        if (!$payload) {
+            return new JsonResponse(array('status' => 'error', 'message' => 'Missing payload parameter'), 406);
         }
 
-        $urlRegex = '{^(?:https?://|git://|git@)?(?P<host>bitbucket\.org)[/:](?P<path>[\w.-]+/[\w.-]+?)(\.git)?/?$}';
-        $repoUrl = $payload['canon_url'].$payload['repository']['absolute_url'];
+        if (isset($payload['repository']['url'])) { // github/gitlab/anything hook
+            $urlRegex = '{^(?:https?://|git://|git@)?(?P<host>[a-z0-9.-]+)[:/](?P<path>[\w.-]+/[\w.-]+?)(?:\.git)?$}';
+            $url = $payload['repository']['url'];
+        } elseif (isset($payload['canon_url']) && isset($payload['repository']['absolute_url'])) { // bitbucket hook
+            $urlRegex = '{^(?:https?://|git://|git@)?(?P<host>bitbucket\.org)[/:](?P<path>[\w.-]+/[\w.-]+?)(\.git)?/?$}';
+            $url = $payload['canon_url'].$payload['repository']['absolute_url'];
+        } else {
+            return new JsonResponse(array('status' => 'error', 'message' => 'Missing or invalid payload'), 406);
+        }
 
-        return $this->receivePost($request, $repoUrl, $urlRegex);
+        return $this->receivePost($request, $url, $urlRegex);
     }
 
     /**

+ 2 - 0
src/Packagist/WebBundle/Resources/views/About/about.html.twig

@@ -83,6 +83,8 @@ v2.0.4-p1
 
         <p>It is highly recommended to set up the <strong>GitHub service hook</strong> for all your packages. This reduces the load on our side, and ensures your package is updated almost instantly. To do so you can go to your GitHub repository, click the "Admin" button, then "Service Hooks". Pick "Packagist" in the list, and add the API key you will find on your <a href="{{ path('fos_user_profile_show') }}">profile</a>, plus your Packagist username if it is not the same as on GitHub. Check the "Active" box and submit the form.</p>
 
+        <p>If you use <strong>BitBucket</strong> or <strong>GitLab</strong> you can add a "POST" hook or Push Event and then enter 'https://packagist.org/api/update-package?username=XXX&amp;apiToken=YYY' as the URL. To manually send update notices from other services you can build up a POST request to the previous URL and send the following JSON request body: <code>{"repository": { "url": "...the VCS url Packagist should update..."}}</code>. Do not forget to send a Content-Type header set to application/json too.</p>
+
         <p>The search index is updated <strong>every five minutes</strong>. It will index (or reindex) any package that has been crawled since the last time the search indexer ran.</p>
 
         <h1>Community</h1>

+ 4 - 6
src/Packagist/WebBundle/Tests/Controller/ApiControllerTest.php

@@ -114,20 +114,18 @@ class ApiControllerTest extends WebTestCase
             array('bitbucket', 'http://bitbucket.org/user/repo', true),
             array('bitbucket', 'https://bitbucket.org/user/repo', true),
 
+            // valid others
+            array('update-package', 'https://ghe.example.org/user/repository', true),
+            array('update-package', 'https://gitlab.org/user/repository', true),
+
             // invalid URLs
             array('github', 'php://github.com/user/repository', false),
             array('github', 'javascript://github.com/user/repository', false),
             array('github', 'http://', false),
-            array('github', 'http://thisisnotgithub.com/user/repository', false),
-            array('github', 'http://thisisnotbitbucket.org/user/repository', false),
-            array('github', 'githubcom/user/repository', false),
-            array('github', 'githubXcom/user/repository', false),
             array('github', 'https://github.com/user/', false),
             array('github', 'https://github.com/user', false),
             array('github', 'https://github.com/', false),
             array('github', 'https://github.com', false),
-            array('bitbucket', 'bitbucketorg/user/repository', false),
-            array('bitbucket', 'bitbucketXorg/user/repository', false),
         );
     }
 }