├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml.dist ├── src ├── Event │ ├── AbstractEvent.php │ ├── IssueEvent.php │ ├── MergeRequestEvent.php │ ├── PingEvent.php │ └── PushEvent.php ├── EventFactory.php ├── Provider │ ├── AbstractProvider.php │ ├── GithubProvider.php │ ├── GitlabProvider.php │ └── ProviderInterface.php ├── Struct │ ├── Commit.php │ ├── Repository.php │ └── User.php └── Util.php └── tests ├── Provider ├── GithubProviderTest.php ├── GitlabProviderTest.php └── _files │ ├── github │ ├── ping.json │ ├── pull_request.json │ ├── push.json │ └── tag.json │ └── gitlab │ ├── issue.json │ ├── merge_request.json │ ├── push.json │ └── tag.json └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | composer.lock -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | sudo: false 4 | 5 | cache: 6 | directories: 7 | - $HOME/.composer/cache 8 | - vendor 9 | 10 | php: 11 | - 5.4 12 | - 5.5 13 | - 5.6 14 | - 7 15 | - hhvm 16 | 17 | env: 18 | matrix: 19 | - PREFER_LOWEST="--prefer-lowest" 20 | - PREFER_LOWEST="" 21 | 22 | matrix: 23 | allow_failures: 24 | - php: hhvm 25 | 26 | before_script: 27 | - composer self-update 28 | - composer update $PREFER_LOWEST 29 | 30 | script: 31 | - vendor/bin/phpunit 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 David Badura 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # git-webhooks 2 | 3 | [![Build Status](https://travis-ci.org/DavidBadura/git-webhooks.svg?branch=master)](https://travis-ci.org/DavidBadura/git-webhooks) 4 | [![Latest Stable Version](https://poser.pugx.org/davidbadura/git-webhooks/v/stable)](https://packagist.org/packages/davidbadura/git-webhooks) 5 | [![Total Downloads](https://poser.pugx.org/davidbadura/git-webhooks/downloads)](https://packagist.org/packages/davidbadura/git-webhooks) 6 | [![Latest Unstable Version](https://poser.pugx.org/davidbadura/git-webhooks/v/unstable)](https://packagist.org/packages/davidbadura/git-webhooks) 7 | [![License](https://poser.pugx.org/davidbadura/git-webhooks/license)](https://packagist.org/packages/davidbadura/git-webhooks) 8 | 9 | normalise webhook events for github, gitlab and bitbucket 10 | 11 | Installation 12 | ------------ 13 | 14 | ```bash 15 | composer require davidbadura/git-webhooks 16 | ``` 17 | 18 | Example 19 | ------- 20 | 21 | ```php 22 | use DavidBadura\GitWebhooks\EventFactory; 23 | use Symfony\Component\HttpFoundation\Request; 24 | 25 | $request = Request::createFromGlobals(); 26 | $factory = EventFactory::createDefault(); 27 | 28 | if ($event = $factory->create($request)) { 29 | // ... 30 | } 31 | ``` -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "davidbadura/git-webhooks", 3 | "description": "normalise webhook events for github, gitlab and bitbucket", 4 | "type": "lib", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "DavidBadura", 9 | "email": "d.a.badura@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": "^5.4 || ^7.0", 14 | "symfony/http-foundation": "^2.7 || ^3.0" 15 | }, 16 | "require-dev": { 17 | "phpunit/phpunit": "^4.7", 18 | "symfony/var-dumper": "^2.7 || ^3.0" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "DavidBadura\\GitWebhooks\\": "src/" 23 | } 24 | }, 25 | "autoload-dev": { 26 | "psr-4": { 27 | "DavidBadura\\GitWebhooks\\": "tests/" 28 | } 29 | }, 30 | "minimum-stability": "stable" 31 | } 32 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | tests 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Event/AbstractEvent.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | abstract class AbstractEvent 12 | { 13 | /** 14 | * @var string 15 | */ 16 | public $provider; 17 | 18 | /** 19 | * @var User 20 | */ 21 | public $user; 22 | 23 | /** 24 | * @var Repository 25 | */ 26 | public $repository; 27 | } -------------------------------------------------------------------------------- /src/Event/IssueEvent.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | class IssueEvent extends AbstractEvent 9 | { 10 | const ACTION_OPEN = 'open'; 11 | const ACTION_CLOSE = 'close'; 12 | 13 | /** 14 | * @var int 15 | */ 16 | public $id; 17 | 18 | /** 19 | * @var string 20 | */ 21 | public $title; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $description; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $action; 32 | } -------------------------------------------------------------------------------- /src/Event/MergeRequestEvent.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class MergeRequestEvent extends AbstractEvent 12 | { 13 | const STATE_OPEN = 'opened'; // todo fix value 14 | const STATE_MERGED = 'merged'; 15 | const STATE_CLOSED = 'closed'; 16 | 17 | /** 18 | * @deprecated 19 | */ 20 | const STATE_OPENED = self::STATE_OPEN; 21 | 22 | /** 23 | * @var int 24 | */ 25 | public $id; 26 | 27 | /** 28 | * @var string 29 | */ 30 | public $title; 31 | 32 | /** 33 | * @var string 34 | */ 35 | public $description; 36 | 37 | /** 38 | * @var Repository 39 | */ 40 | public $sourceRepository; 41 | 42 | /** 43 | * @var string 44 | */ 45 | public $targetBranch; 46 | 47 | /** 48 | * @var string 49 | */ 50 | public $sourceBranch; 51 | 52 | /** 53 | * @var string 54 | */ 55 | public $state; 56 | 57 | /** 58 | * @var Commit 59 | */ 60 | public $lastCommit; 61 | 62 | /** 63 | * @var \DateTime 64 | */ 65 | public $createdAt; 66 | 67 | /** 68 | * @var \DateTime 69 | */ 70 | public $updatedAt; 71 | } -------------------------------------------------------------------------------- /src/Event/PingEvent.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | class PingEvent extends AbstractEvent 9 | { 10 | /** 11 | * @var int 12 | */ 13 | public $id; 14 | 15 | /** 16 | * @var string 17 | */ 18 | public $title; 19 | 20 | /** 21 | * @var string 22 | */ 23 | public $description; 24 | 25 | /** 26 | * @var string 27 | */ 28 | public $action; 29 | } -------------------------------------------------------------------------------- /src/Event/PushEvent.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class PushEvent extends AbstractEvent 12 | { 13 | const TYPE_BRANCH = 'branch'; 14 | const TYPE_TAG = 'tag'; 15 | 16 | /** 17 | * @var string 18 | */ 19 | public $before; 20 | 21 | /** 22 | * @var string 23 | */ 24 | public $after; 25 | 26 | /** 27 | * @var string 28 | */ 29 | public $ref; 30 | 31 | /** 32 | * @var string 33 | */ 34 | public $type; 35 | 36 | /** 37 | * @var string 38 | */ 39 | public $branchName; 40 | 41 | /** 42 | * @var string 43 | */ 44 | public $tagName; 45 | 46 | /** 47 | * @var Repository 48 | */ 49 | public $repository; 50 | 51 | /** 52 | * @var Commit[] 53 | */ 54 | public $commits = []; 55 | } -------------------------------------------------------------------------------- /src/EventFactory.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class EventFactory 15 | { 16 | /** 17 | * @var ProviderInterface[] 18 | */ 19 | protected $providers = []; 20 | 21 | /** 22 | * @param ProviderInterface[] $providers 23 | */ 24 | public function __construct(array $providers = []) 25 | { 26 | foreach ($providers as $provider) { 27 | $this->addProvider($provider); 28 | } 29 | } 30 | 31 | /** 32 | * @param Request $request 33 | * @return AbstractEvent 34 | */ 35 | public function create(Request $request) 36 | { 37 | foreach ($this->providers as $provider) { 38 | if (!$provider->support($request)) { 39 | continue; 40 | } 41 | 42 | return $provider->create($request); 43 | } 44 | } 45 | 46 | /** 47 | * @param ProviderInterface $provider 48 | * @return $this 49 | */ 50 | public function addProvider(ProviderInterface $provider) 51 | { 52 | $this->providers[] = $provider; 53 | 54 | return $this; 55 | } 56 | 57 | /** 58 | * @return self 59 | */ 60 | public static function createDefault() 61 | { 62 | return new self([ 63 | new GitlabProvider(), 64 | new GithubProvider() 65 | ]); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Provider/AbstractProvider.php: -------------------------------------------------------------------------------- 1 | getContent(); 17 | 18 | return json_decode($body, true); 19 | } 20 | 21 | /** 22 | * @param array $data 23 | * @return Commit[] 24 | */ 25 | protected function createCommits(array $data) 26 | { 27 | $result = []; 28 | 29 | foreach ($data as $row) { 30 | $result[] = $this->createCommit($row); 31 | } 32 | 33 | return $result; 34 | } 35 | 36 | abstract protected function createCommit(array $data); 37 | } -------------------------------------------------------------------------------- /src/Provider/GithubProvider.php: -------------------------------------------------------------------------------- 1 | getData($request); 26 | switch ($request->headers->get('X-Github-Event')) { 27 | case 'ping': 28 | return $this->createPingEvent($data); 29 | case 'push': 30 | return $this->createPushEvent($data); 31 | case 'pull_request': 32 | return $this->createMergeRequestEvent($data); 33 | default: 34 | return null; 35 | } 36 | } 37 | 38 | /** 39 | * @param Request $request 40 | * @return bool 41 | */ 42 | public function support(Request $request) 43 | { 44 | return $request->headers->has('X-GitHub-Event'); 45 | } 46 | 47 | /** 48 | * @param array $data 49 | * @return PingEvent 50 | */ 51 | private function createPingEvent($data) 52 | { 53 | $event = new PingEvent(); 54 | $event->provider = self::NAME; 55 | $event->repository = $this->createRepository($data['repository']); 56 | 57 | return $event; 58 | } 59 | 60 | /** 61 | * @param array $data 62 | * @return PushEvent 63 | */ 64 | private function createPushEvent($data) 65 | { 66 | $event = new PushEvent(); 67 | $event->provider = self::NAME; 68 | $event->before = $data['before']; 69 | $event->after = $data['after']; 70 | $event->ref = $data['ref']; 71 | 72 | $user = new User(); 73 | $user->id = $data['sender']['id']; 74 | $user->name = $data['pusher']['name']; 75 | 76 | if (isset($data['pusher']['email'])) { 77 | $user->email = $data['pusher']['email']; 78 | } 79 | 80 | $event->user = $user; 81 | $event->repository = $this->createRepository($data['repository']); 82 | $event->commits = $this->createCommits($data['commits']); 83 | 84 | if (!$event->commits and $data['head_commit']) { 85 | $event->commits[] = $this->createCommit($data['head_commit']); 86 | } 87 | 88 | $event->type = Util::getPushType($event->ref); 89 | 90 | if ($event->type == PushEvent::TYPE_BRANCH) { 91 | $event->branchName = Util::getBranchName($event->ref); 92 | } else { 93 | $event->tagName = Util::getTagName($event->ref); 94 | } 95 | 96 | return $event; 97 | } 98 | 99 | /** 100 | * @param array $data 101 | * @return MergeRequestEvent 102 | */ 103 | private function createMergeRequestEvent(array $data) 104 | { 105 | $event = new MergeRequestEvent(); 106 | 107 | $event->provider = self::NAME; 108 | $event->id = $data['pull_request']['id']; 109 | $event->title = $data['pull_request']['title']; 110 | $event->description = $data['pull_request']['body']; 111 | 112 | $event->targetBranch = $data['pull_request']['base']['ref']; 113 | $event->sourceBranch = $data['pull_request']['head']['ref']; 114 | $event->state = $this->pullRequestState($data['pull_request']); 115 | $event->createdAt = new \DateTime($data['pull_request']['created_at']); 116 | $event->updatedAt = new \DateTime($data['pull_request']['updated_at']); 117 | 118 | $user = new User(); 119 | $user->id = $data['pull_request']['user']['id']; 120 | $user->name = $data['pull_request']['user']['login']; 121 | 122 | $event->user = $user; 123 | $event->repository = $this->createRepository($data['pull_request']['base']['repo']); 124 | $event->sourceRepository = $this->createRepository($data['pull_request']['head']['repo']); 125 | 126 | // TODO request data from $data['pull_request']['commits_url'] 127 | $event->lastCommit = new Commit(); 128 | $event->lastCommit->id = $data['pull_request']['head']['sha']; 129 | 130 | return $event; 131 | } 132 | 133 | /** 134 | * @param array $data 135 | * @return Repository 136 | */ 137 | private function createRepository(array $data) 138 | { 139 | $repository = new Repository(); 140 | 141 | $repository->id = $data['id']; 142 | $repository->name = $data['name']; 143 | $repository->description = $data['description']; 144 | $repository->namespace = $this->extractNamespace($data['full_name']); 145 | $repository->url = $data['ssh_url']; 146 | $repository->homepage = $data['html_url']; 147 | 148 | return $repository; 149 | } 150 | 151 | /** 152 | * @param array $data 153 | * @return Commit 154 | */ 155 | protected function createCommit(array $data) 156 | { 157 | $commit = new Commit(); 158 | 159 | $commit->id = $data['id']; 160 | $commit->message = $data['message']; 161 | $commit->date = new \DateTime($data['timestamp']); 162 | 163 | $user = new User(); 164 | $user->name = $data['author']['name']; 165 | $user->email = $data['author']['email']; 166 | 167 | $commit->author = $user; 168 | 169 | return $commit; 170 | } 171 | 172 | /** 173 | * @param string $fullName 174 | * @return string 175 | */ 176 | private function extractNamespace($fullName) 177 | { 178 | $parts = explode('/', $fullName); 179 | 180 | return $parts[0]; 181 | } 182 | 183 | /** 184 | * @param array $pullRequest 185 | * @return string 186 | */ 187 | private function pullRequestState(array $pullRequest) 188 | { 189 | if ($pullRequest['state'] === 'open') { 190 | return MergeRequestEvent::STATE_OPEN; 191 | } 192 | 193 | if ($pullRequest['merged_at']) { 194 | return MergeRequestEvent::STATE_MERGED; 195 | } 196 | 197 | return MergeRequestEvent::STATE_CLOSED; 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/Provider/GitlabProvider.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class GitlabProvider extends AbstractProvider implements ProviderInterface 19 | { 20 | const NAME = 'gitlab'; 21 | 22 | /** 23 | * @param Request $request 24 | * @return AbstractEvent 25 | */ 26 | public function create(Request $request) 27 | { 28 | $data = $this->getData($request); 29 | 30 | if (!$data) { 31 | return null; 32 | } 33 | 34 | switch ($request->headers->get('X-Gitlab-Event')) { 35 | case 'Push Hook': 36 | case 'Tag Push Hook': 37 | return $this->createPushEvent($data); 38 | case 'Issue Hook': 39 | return $this->createIssueEvent($data); 40 | case 'Merge Request Hook': 41 | return $this->createMergeRequestEvent($data); 42 | default: 43 | return null; 44 | } 45 | } 46 | 47 | /** 48 | * @param Request $request 49 | * @return bool 50 | */ 51 | public function support(Request $request) 52 | { 53 | return $request->headers->has('X-Gitlab-Event'); 54 | } 55 | 56 | /** 57 | * @param array $data 58 | * @return IssueEvent 59 | */ 60 | private function createIssueEvent(array $data) 61 | { 62 | // todo 63 | } 64 | 65 | /** 66 | * @param array $data 67 | * @return MergeRequestEvent 68 | */ 69 | private function createMergeRequestEvent(array $data) 70 | { 71 | $event = new MergeRequestEvent(); 72 | $event->provider = self::NAME; 73 | $event->id = $data['object_attributes']['iid']; 74 | $event->title = $data['object_attributes']['title']; 75 | $event->description = $data['object_attributes']['description']; 76 | $event->targetBranch = $data['object_attributes']['target_branch']; 77 | $event->sourceBranch = $data['object_attributes']['source_branch']; 78 | $event->state = $data['object_attributes']['state']; 79 | $event->createdAt = new \DateTime($data['object_attributes']['created_at']); 80 | $event->updatedAt = new \DateTime($data['object_attributes']['updated_at']); 81 | 82 | $user = new User(); 83 | $user->id = $data['object_attributes']['author_id']; 84 | $user->name = $data['user']['name']; 85 | 86 | $targetRepository = new Repository(); 87 | $targetRepository->id = $data['object_attributes']['target_project_id']; 88 | $targetRepository->name = $data['object_attributes']['target']['name']; 89 | $targetRepository->namespace = $data['object_attributes']['target']['namespace']; 90 | $targetRepository->url = $data['object_attributes']['target']['ssh_url']; 91 | 92 | $sourceProject = new Repository(); 93 | $sourceProject->id = $data['object_attributes']['source_project_id']; 94 | $sourceProject->name = $data['object_attributes']['source']['name']; 95 | $sourceProject->namespace = $data['object_attributes']['source']['namespace']; 96 | $sourceProject->url = $data['object_attributes']['source']['ssh_url']; 97 | 98 | $event->user = $user; 99 | $event->repository = $targetRepository; 100 | $event->sourceRepository = $sourceProject; 101 | $event->lastCommit = $this->createCommit($data['object_attributes']['last_commit']); 102 | 103 | return $event; 104 | } 105 | 106 | /** 107 | * @param array $data 108 | * @return PushEvent 109 | */ 110 | private function createPushEvent(array $data) 111 | { 112 | $event = new PushEvent(); 113 | $event->provider = self::NAME; 114 | $event->before = $data['before']; 115 | $event->after = $data['after']; 116 | $event->ref = $data['ref']; 117 | 118 | $user = new User(); 119 | $user->id = $data['user_id']; 120 | $user->name = $data['user_name']; 121 | 122 | if (isset($data['user_email'])) { 123 | $user->email = $data['user_email']; 124 | } 125 | 126 | $repository = new Repository(); 127 | $repository->id = $data['project_id']; 128 | $repository->name = $data['project']['name']; 129 | $repository->namespace = $data['project']['namespace']; 130 | $repository->description = $data['project']['description']; 131 | $repository->homepage = $data['project']['homepage']; 132 | $repository->url = $data['project']['url']; 133 | 134 | $event->user = $user; 135 | $event->repository = $repository; 136 | $event->commits = $this->createCommits($data['commits']); 137 | 138 | $event->type = Util::getPushType($event->ref); 139 | 140 | if ($event->type == PushEvent::TYPE_BRANCH) { 141 | $event->branchName = Util::getBranchName($event->ref); 142 | } else { 143 | $event->tagName = Util::getTagName($event->ref); 144 | } 145 | 146 | return $event; 147 | } 148 | 149 | /** 150 | * @param array $data 151 | * @return Commit 152 | */ 153 | protected function createCommit(array $data) 154 | { 155 | $commit = new Commit(); 156 | 157 | $commit->id = $data['id']; 158 | $commit->message = $data['message']; 159 | $commit->date = new \DateTime($data['timestamp']); 160 | 161 | $user = new User(); 162 | $user->name = $data['author']['name']; 163 | $user->email = $data['author']['email']; 164 | 165 | $commit->author = $user; 166 | 167 | return $commit; 168 | } 169 | } -------------------------------------------------------------------------------- /src/Provider/ProviderInterface.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | interface ProviderInterface 12 | { 13 | /** 14 | * @param Request $request 15 | * @return AbstractEvent 16 | */ 17 | public function create(Request $request); 18 | 19 | /** 20 | * @param Request $request 21 | * @return bool 22 | */ 23 | public function support(Request $request); 24 | } -------------------------------------------------------------------------------- /src/Struct/Commit.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | class Commit 9 | { 10 | /** 11 | * @var string 12 | */ 13 | public $id; 14 | 15 | /** 16 | * @var string 17 | */ 18 | public $message; 19 | 20 | /** 21 | * @var \DateTime 22 | */ 23 | public $date; 24 | 25 | /** 26 | * @var User 27 | */ 28 | public $author; 29 | } -------------------------------------------------------------------------------- /src/Struct/Repository.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | class Repository 9 | { 10 | /** 11 | * @var int 12 | */ 13 | public $id; 14 | 15 | /** 16 | * @var string 17 | */ 18 | public $name; 19 | 20 | /** 21 | * @var string 22 | */ 23 | public $namespace; 24 | 25 | /** 26 | * @var string 27 | */ 28 | public $description; 29 | 30 | /** 31 | * @var string 32 | */ 33 | public $homepage; 34 | 35 | /** 36 | * @var string 37 | */ 38 | public $url; 39 | } -------------------------------------------------------------------------------- /src/Struct/User.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | class User 9 | { 10 | /** 11 | * @var string 12 | */ 13 | public $id; 14 | 15 | /** 16 | * @var string 17 | */ 18 | public $name; 19 | 20 | /** 21 | * @var string 22 | */ 23 | public $email; 24 | } -------------------------------------------------------------------------------- /src/Util.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | class Util 14 | { 15 | /** 16 | * @param string $ref 17 | * @return string 18 | */ 19 | public static function getPushType($ref) 20 | { 21 | if (strpos($ref, 'refs/tags/') === 0) { 22 | return PushEvent::TYPE_TAG; 23 | } 24 | 25 | if (strpos($ref, 'refs/heads/') === 0) { 26 | return PushEvent::TYPE_BRANCH; 27 | } 28 | 29 | throw new \InvalidArgumentException("type not supported"); 30 | } 31 | 32 | /** 33 | * @param string $ref 34 | * @return string 35 | */ 36 | public static function getBranchName($ref) 37 | { 38 | if (self::getPushType($ref) != PushEvent::TYPE_BRANCH) { 39 | throw new \InvalidArgumentException("ref isn't a branch"); 40 | } 41 | 42 | return substr($ref, 11); 43 | } 44 | 45 | /** 46 | * @param string $ref 47 | * @return string 48 | */ 49 | public static function getTagName($ref) 50 | { 51 | if (self::getPushType($ref) != PushEvent::TYPE_TAG) { 52 | throw new \InvalidArgumentException("ref isn't a tag"); 53 | } 54 | 55 | return substr($ref, 10); 56 | } 57 | } -------------------------------------------------------------------------------- /tests/Provider/GithubProviderTest.php: -------------------------------------------------------------------------------- 1 | createRequest('foo'); 14 | 15 | $provider = new GithubProvider(); 16 | 17 | $this->assertTrue($provider->support($request)); 18 | } 19 | 20 | public function testNoSupport() 21 | { 22 | $request = new Request(); 23 | 24 | $provider = new GithubProvider(); 25 | 26 | $this->assertFalse($provider->support($request)); 27 | } 28 | 29 | public function testPush() 30 | { 31 | $request = $this->createRequest('push', __DIR__ . '/_files/github/push.json'); 32 | 33 | $provider = new GithubProvider(); 34 | /** @var PushEvent $event */ 35 | $event = $provider->create($request); 36 | 37 | $this->assertInstanceOf('DavidBadura\GitWebhooks\Event\PushEvent', $event); 38 | $this->assertEquals('refs/heads/changes', $event->ref); 39 | $this->assertEquals('changes', $event->branchName); 40 | $this->assertEquals(null, $event->tagName); 41 | $this->assertEquals('baxterthehacker', $event->user->name); 42 | $this->assertEquals('public-repo', $event->repository->name); 43 | $this->assertEquals('baxterthehacker', $event->repository->namespace); 44 | $this->assertCount(1, $event->commits); 45 | } 46 | 47 | public function testTag() 48 | { 49 | $request = $this->createRequest('push', __DIR__ . '/_files/github/tag.json'); 50 | 51 | $provider = new GithubProvider(); 52 | /** @var PushEvent $event */ 53 | $event = $provider->create($request); 54 | 55 | $this->assertInstanceOf('DavidBadura\GitWebhooks\Event\PushEvent', $event); 56 | $this->assertEquals('refs/tags/test-tag', $event->ref); 57 | $this->assertEquals(null, $event->branchName); 58 | $this->assertEquals('test-tag', $event->tagName); 59 | $this->assertEquals('public-repo', $event->repository->name); 60 | $this->assertEquals('baxterthehacker', $event->repository->namespace); 61 | $this->assertCount(1, $event->commits); 62 | $this->assertEquals('0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c', $event->commits[0]->id); 63 | } 64 | 65 | public function testPullRequest() 66 | { 67 | $request = $this->createRequest('pull_request', __DIR__ . '/_files/github/pull_request.json'); 68 | 69 | $provider = new GithubProvider(); 70 | 71 | /** @var MergeRequestEvent $event */ 72 | $event = $provider->create($request); 73 | 74 | $this->assertInstanceOf('DavidBadura\GitWebhooks\Event\MergeRequestEvent', $event); 75 | $this->assertEquals('opened', $event->state); 76 | $this->assertEquals('Update the README with new information', $event->title); 77 | $this->assertEquals('This is a pretty simple change that we need to pull into master.', $event->description); 78 | $this->assertEquals('master', $event->targetBranch); 79 | $this->assertEquals('changes', $event->sourceBranch); 80 | $this->assertEquals('public-repo', $event->repository->name); 81 | $this->assertEquals('baxterthehacker', $event->repository->namespace); 82 | $this->assertEquals('public-repo', $event->sourceRepository->name); 83 | $this->assertEquals('baxterthehacker', $event->sourceRepository->namespace); 84 | $this->assertEquals('0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c', $event->lastCommit->id); 85 | } 86 | 87 | public function testPingRequest() 88 | { 89 | $request = $this->createRequest('ping', __DIR__ . '/_files/github/ping.json'); 90 | 91 | $provider = new GithubProvider(); 92 | 93 | /** @var MergeRequestEvent $event */ 94 | $event = $provider->create($request); 95 | 96 | $this->assertInstanceOf('DavidBadura\GitWebhooks\Event\PingEvent', $event); 97 | $this->assertEquals('simpspector', $event->repository->name); 98 | $this->assertEquals('simpspector', $event->repository->namespace); 99 | } 100 | 101 | /** 102 | * @param string $event 103 | * @param string $file 104 | * @return Request 105 | */ 106 | protected function createRequest($event, $file = null) 107 | { 108 | $content = null; 109 | 110 | if ($file) { 111 | $content = file_get_contents($file); 112 | } 113 | 114 | $request = new Request([], [], [], [], [], [], $content); 115 | $request->headers->set('X-Github-Event', $event); 116 | 117 | return $request; 118 | } 119 | } -------------------------------------------------------------------------------- /tests/Provider/GitlabProviderTest.php: -------------------------------------------------------------------------------- 1 | createRequest('foo'); 14 | 15 | $provider = new GitlabProvider(); 16 | 17 | $this->assertTrue($provider->support($request)); 18 | } 19 | 20 | public function testNoSupport() 21 | { 22 | $request = new Request(); 23 | 24 | $provider = new GitlabProvider(); 25 | 26 | $this->assertFalse($provider->support($request)); 27 | } 28 | 29 | public function testPush() 30 | { 31 | $request = $this->createRequest('Push Hook', __DIR__ . '/_files/gitlab/push.json'); 32 | 33 | $provider = new GitlabProvider(); 34 | 35 | /** @var PushEvent $event */ 36 | $event = $provider->create($request); 37 | 38 | $this->assertInstanceOf('DavidBadura\GitWebhooks\Event\PushEvent', $event); 39 | $this->assertEquals('refs/heads/master', $event->ref); 40 | $this->assertEquals('master', $event->branchName); 41 | $this->assertEquals(null, $event->tagName); 42 | $this->assertEquals('John Smith', $event->user->name); 43 | $this->assertEquals('Diaspora', $event->repository->name); 44 | $this->assertEquals('Mike', $event->repository->namespace); 45 | $this->assertCount(2, $event->commits); 46 | } 47 | 48 | public function testTag() 49 | { 50 | $request = $this->createRequest('Tag Push Hook', __DIR__ . '/_files/gitlab/tag.json'); 51 | 52 | $provider = new GitlabProvider(); 53 | 54 | /** @var PushEvent $event */ 55 | $event = $provider->create($request); 56 | 57 | $this->assertInstanceOf('DavidBadura\GitWebhooks\Event\PushEvent', $event); 58 | $this->assertEquals('refs/tags/v1.0.0', $event->ref); 59 | $this->assertEquals(null, $event->branchName); 60 | $this->assertEquals('v1.0.0', $event->tagName); 61 | $this->assertEquals('Example', $event->repository->name); 62 | $this->assertEquals('Jsmith', $event->repository->namespace); 63 | } 64 | 65 | public function testMergeRequest() 66 | { 67 | $request = $this->createRequest('Merge Request Hook', __DIR__ . '/_files/gitlab/merge_request.json'); 68 | 69 | $provider = new GitlabProvider(); 70 | 71 | /** @var MergeRequestEvent $event */ 72 | $event = $provider->create($request); 73 | 74 | $this->assertInstanceOf('DavidBadura\GitWebhooks\Event\MergeRequestEvent', $event); 75 | $this->assertEquals('opened', $event->state); 76 | $this->assertEquals('MS-Viewport', $event->title); 77 | $this->assertEquals('', $event->description); 78 | $this->assertEquals('master', $event->targetBranch); 79 | $this->assertEquals('ms-viewport', $event->sourceBranch); 80 | $this->assertEquals('Awesome Project', $event->repository->name); 81 | $this->assertEquals('Awesome Space', $event->repository->namespace); 82 | $this->assertEquals('Awesome Project', $event->sourceRepository->name); 83 | $this->assertEquals('Awesome Space', $event->sourceRepository->namespace); 84 | $this->assertEquals('da1560886d4f094c3e6c9ef40349f7d38b5d27d7', $event->lastCommit->id); 85 | } 86 | 87 | /** 88 | * @param string $event 89 | * @param string $file 90 | * @return Request 91 | */ 92 | protected function createRequest($event, $file = null) 93 | { 94 | $content = null; 95 | 96 | if ($file) { 97 | $content = file_get_contents($file); 98 | } 99 | 100 | $request = new Request([], [], [], [], [], [], $content); 101 | $request->headers->set('X-Gitlab-Event', $event); 102 | 103 | return $request; 104 | } 105 | } -------------------------------------------------------------------------------- /tests/Provider/_files/github/ping.json: -------------------------------------------------------------------------------- 1 | { 2 | "zen": "Speak like a human.", 3 | "hook_id": 11668534, 4 | "hook": { 5 | "type": "Repository", 6 | "id": 11668534, 7 | "name": "web", 8 | "active": true, 9 | "events": [ 10 | "commit_comment", 11 | "push" 12 | ], 13 | "config": { 14 | "content_type": "form", 15 | "insecure_ssl": "0", 16 | "url": "https://simpspector.wallenborn.net/hooks" 17 | }, 18 | "updated_at": "2017-01-23T08:47:37Z", 19 | "created_at": "2017-01-23T08:47:37Z", 20 | "url": "https://api.github.com/repos/simpspector/simpspector/hooks/11668534", 21 | "test_url": "https://api.github.com/repos/simpspector/simpspector/hooks/11668534/test", 22 | "ping_url": "https://api.github.com/repos/simpspector/simpspector/hooks/11668534/pings", 23 | "last_response": { 24 | "code": null, 25 | "status": "unused", 26 | "message": null 27 | } 28 | }, 29 | "repository": { 30 | "id": 26141279, 31 | "name": "simpspector", 32 | "full_name": "simpspector/simpspector", 33 | "owner": { 34 | "login": "simpspector", 35 | "id": 11267955, 36 | "avatar_url": "https://avatars.githubusercontent.com/u/11267955?v=3", 37 | "gravatar_id": "", 38 | "url": "https://api.github.com/users/simpspector", 39 | "html_url": "https://github.com/simpspector", 40 | "followers_url": "https://api.github.com/users/simpspector/followers", 41 | "following_url": "https://api.github.com/users/simpspector/following{/other_user}", 42 | "gists_url": "https://api.github.com/users/simpspector/gists{/gist_id}", 43 | "starred_url": "https://api.github.com/users/simpspector/starred{/owner}{/repo}", 44 | "subscriptions_url": "https://api.github.com/users/simpspector/subscriptions", 45 | "organizations_url": "https://api.github.com/users/simpspector/orgs", 46 | "repos_url": "https://api.github.com/users/simpspector/repos", 47 | "events_url": "https://api.github.com/users/simpspector/events{/privacy}", 48 | "received_events_url": "https://api.github.com/users/simpspector/received_events", 49 | "type": "Organization", 50 | "site_admin": false 51 | }, 52 | "private": false, 53 | "html_url": "https://github.com/simpspector/simpspector", 54 | "description": ":eyes: SimpleThings Code Inspector for gitlab and github (almost alpha) - Metrics, Static Code Analytics, Coding Standards, ...", 55 | "fork": false, 56 | "url": "https://api.github.com/repos/simpspector/simpspector", 57 | "forks_url": "https://api.github.com/repos/simpspector/simpspector/forks", 58 | "keys_url": "https://api.github.com/repos/simpspector/simpspector/keys{/key_id}", 59 | "collaborators_url": "https://api.github.com/repos/simpspector/simpspector/collaborators{/collaborator}", 60 | "teams_url": "https://api.github.com/repos/simpspector/simpspector/teams", 61 | "hooks_url": "https://api.github.com/repos/simpspector/simpspector/hooks", 62 | "issue_events_url": "https://api.github.com/repos/simpspector/simpspector/issues/events{/number}", 63 | "events_url": "https://api.github.com/repos/simpspector/simpspector/events", 64 | "assignees_url": "https://api.github.com/repos/simpspector/simpspector/assignees{/user}", 65 | "branches_url": "https://api.github.com/repos/simpspector/simpspector/branches{/branch}", 66 | "tags_url": "https://api.github.com/repos/simpspector/simpspector/tags", 67 | "blobs_url": "https://api.github.com/repos/simpspector/simpspector/git/blobs{/sha}", 68 | "git_tags_url": "https://api.github.com/repos/simpspector/simpspector/git/tags{/sha}", 69 | "git_refs_url": "https://api.github.com/repos/simpspector/simpspector/git/refs{/sha}", 70 | "trees_url": "https://api.github.com/repos/simpspector/simpspector/git/trees{/sha}", 71 | "statuses_url": "https://api.github.com/repos/simpspector/simpspector/statuses/{sha}", 72 | "languages_url": "https://api.github.com/repos/simpspector/simpspector/languages", 73 | "stargazers_url": "https://api.github.com/repos/simpspector/simpspector/stargazers", 74 | "contributors_url": "https://api.github.com/repos/simpspector/simpspector/contributors", 75 | "subscribers_url": "https://api.github.com/repos/simpspector/simpspector/subscribers", 76 | "subscription_url": "https://api.github.com/repos/simpspector/simpspector/subscription", 77 | "commits_url": "https://api.github.com/repos/simpspector/simpspector/commits{/sha}", 78 | "git_commits_url": "https://api.github.com/repos/simpspector/simpspector/git/commits{/sha}", 79 | "comments_url": "https://api.github.com/repos/simpspector/simpspector/comments{/number}", 80 | "issue_comment_url": "https://api.github.com/repos/simpspector/simpspector/issues/comments{/number}", 81 | "contents_url": "https://api.github.com/repos/simpspector/simpspector/contents/{+path}", 82 | "compare_url": "https://api.github.com/repos/simpspector/simpspector/compare/{base}...{head}", 83 | "merges_url": "https://api.github.com/repos/simpspector/simpspector/merges", 84 | "archive_url": "https://api.github.com/repos/simpspector/simpspector/{archive_format}{/ref}", 85 | "downloads_url": "https://api.github.com/repos/simpspector/simpspector/downloads", 86 | "issues_url": "https://api.github.com/repos/simpspector/simpspector/issues{/number}", 87 | "pulls_url": "https://api.github.com/repos/simpspector/simpspector/pulls{/number}", 88 | "milestones_url": "https://api.github.com/repos/simpspector/simpspector/milestones{/number}", 89 | "notifications_url": "https://api.github.com/repos/simpspector/simpspector/notifications{?since,all,participating}", 90 | "labels_url": "https://api.github.com/repos/simpspector/simpspector/labels{/name}", 91 | "releases_url": "https://api.github.com/repos/simpspector/simpspector/releases{/id}", 92 | "deployments_url": "https://api.github.com/repos/simpspector/simpspector/deployments", 93 | "created_at": "2014-11-03T22:12:14Z", 94 | "updated_at": "2017-01-20T14:00:04Z", 95 | "pushed_at": "2017-01-20T13:59:03Z", 96 | "git_url": "git://github.com/simpspector/simpspector.git", 97 | "ssh_url": "git@github.com:simpspector/simpspector.git", 98 | "clone_url": "https://github.com/simpspector/simpspector.git", 99 | "svn_url": "https://github.com/simpspector/simpspector", 100 | "homepage": "", 101 | "size": 1187, 102 | "stargazers_count": 6, 103 | "watchers_count": 6, 104 | "language": "PHP", 105 | "has_issues": true, 106 | "has_downloads": true, 107 | "has_wiki": true, 108 | "has_pages": false, 109 | "forks_count": 1, 110 | "mirror_url": null, 111 | "open_issues_count": 25, 112 | "forks": 1, 113 | "open_issues": 25, 114 | "watchers": 6, 115 | "default_branch": "master" 116 | }, 117 | "sender": { 118 | "login": "larsborn", 119 | "id": 1826897, 120 | "avatar_url": "https://avatars.githubusercontent.com/u/1826897?v=3", 121 | "gravatar_id": "", 122 | "url": "https://api.github.com/users/larsborn", 123 | "html_url": "https://github.com/larsborn", 124 | "followers_url": "https://api.github.com/users/larsborn/followers", 125 | "following_url": "https://api.github.com/users/larsborn/following{/other_user}", 126 | "gists_url": "https://api.github.com/users/larsborn/gists{/gist_id}", 127 | "starred_url": "https://api.github.com/users/larsborn/starred{/owner}{/repo}", 128 | "subscriptions_url": "https://api.github.com/users/larsborn/subscriptions", 129 | "organizations_url": "https://api.github.com/users/larsborn/orgs", 130 | "repos_url": "https://api.github.com/users/larsborn/repos", 131 | "events_url": "https://api.github.com/users/larsborn/events{/privacy}", 132 | "received_events_url": "https://api.github.com/users/larsborn/received_events", 133 | "type": "User", 134 | "site_admin": false 135 | } 136 | } -------------------------------------------------------------------------------- /tests/Provider/_files/github/pull_request.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "opened", 3 | "number": 1, 4 | "pull_request": { 5 | "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1", 6 | "id": 34778301, 7 | "html_url": "https://github.com/baxterthehacker/public-repo/pull/1", 8 | "diff_url": "https://github.com/baxterthehacker/public-repo/pull/1.diff", 9 | "patch_url": "https://github.com/baxterthehacker/public-repo/pull/1.patch", 10 | "issue_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1", 11 | "number": 1, 12 | "state": "open", 13 | "locked": false, 14 | "title": "Update the README with new information", 15 | "user": { 16 | "login": "baxterthehacker", 17 | "id": 6752317, 18 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 19 | "gravatar_id": "", 20 | "url": "https://api.github.com/users/baxterthehacker", 21 | "html_url": "https://github.com/baxterthehacker", 22 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 23 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 24 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 25 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 26 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 27 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 28 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 29 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 30 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 31 | "type": "User", 32 | "site_admin": false 33 | }, 34 | "body": "This is a pretty simple change that we need to pull into master.", 35 | "created_at": "2015-05-05T23:40:27Z", 36 | "updated_at": "2015-05-05T23:40:27Z", 37 | "closed_at": null, 38 | "merged_at": null, 39 | "merge_commit_sha": null, 40 | "assignee": null, 41 | "milestone": null, 42 | "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits", 43 | "review_comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments", 44 | "review_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}", 45 | "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments", 46 | "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 47 | "head": { 48 | "label": "baxterthehacker:changes", 49 | "ref": "changes", 50 | "sha": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 51 | "user": { 52 | "login": "baxterthehacker", 53 | "id": 6752317, 54 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 55 | "gravatar_id": "", 56 | "url": "https://api.github.com/users/baxterthehacker", 57 | "html_url": "https://github.com/baxterthehacker", 58 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 59 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 60 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 61 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 62 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 63 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 64 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 65 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 66 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 67 | "type": "User", 68 | "site_admin": false 69 | }, 70 | "repo": { 71 | "id": 35129377, 72 | "name": "public-repo", 73 | "full_name": "baxterthehacker/public-repo", 74 | "owner": { 75 | "login": "baxterthehacker", 76 | "id": 6752317, 77 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 78 | "gravatar_id": "", 79 | "url": "https://api.github.com/users/baxterthehacker", 80 | "html_url": "https://github.com/baxterthehacker", 81 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 82 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 83 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 84 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 85 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 86 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 87 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 88 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 89 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 90 | "type": "User", 91 | "site_admin": false 92 | }, 93 | "private": false, 94 | "html_url": "https://github.com/baxterthehacker/public-repo", 95 | "description": "", 96 | "fork": false, 97 | "url": "https://api.github.com/repos/baxterthehacker/public-repo", 98 | "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", 99 | "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", 100 | "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", 101 | "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", 102 | "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", 103 | "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", 104 | "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", 105 | "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", 106 | "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", 107 | "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", 108 | "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", 109 | "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", 110 | "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", 111 | "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", 112 | "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", 113 | "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", 114 | "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", 115 | "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", 116 | "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", 117 | "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", 118 | "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", 119 | "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", 120 | "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", 121 | "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", 122 | "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", 123 | "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", 124 | "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", 125 | "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", 126 | "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", 127 | "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", 128 | "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", 129 | "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", 130 | "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", 131 | "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", 132 | "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", 133 | "created_at": "2015-05-05T23:40:12Z", 134 | "updated_at": "2015-05-05T23:40:12Z", 135 | "pushed_at": "2015-05-05T23:40:26Z", 136 | "git_url": "git://github.com/baxterthehacker/public-repo.git", 137 | "ssh_url": "git@github.com:baxterthehacker/public-repo.git", 138 | "clone_url": "https://github.com/baxterthehacker/public-repo.git", 139 | "svn_url": "https://github.com/baxterthehacker/public-repo", 140 | "homepage": null, 141 | "size": 0, 142 | "stargazers_count": 0, 143 | "watchers_count": 0, 144 | "language": null, 145 | "has_issues": true, 146 | "has_downloads": true, 147 | "has_wiki": true, 148 | "has_pages": true, 149 | "forks_count": 0, 150 | "mirror_url": null, 151 | "open_issues_count": 1, 152 | "forks": 0, 153 | "open_issues": 1, 154 | "watchers": 0, 155 | "default_branch": "master" 156 | } 157 | }, 158 | "base": { 159 | "label": "baxterthehacker:master", 160 | "ref": "master", 161 | "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", 162 | "user": { 163 | "login": "baxterthehacker", 164 | "id": 6752317, 165 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 166 | "gravatar_id": "", 167 | "url": "https://api.github.com/users/baxterthehacker", 168 | "html_url": "https://github.com/baxterthehacker", 169 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 170 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 171 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 172 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 173 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 174 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 175 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 176 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 177 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 178 | "type": "User", 179 | "site_admin": false 180 | }, 181 | "repo": { 182 | "id": 35129377, 183 | "name": "public-repo", 184 | "full_name": "baxterthehacker/public-repo", 185 | "owner": { 186 | "login": "baxterthehacker", 187 | "id": 6752317, 188 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 189 | "gravatar_id": "", 190 | "url": "https://api.github.com/users/baxterthehacker", 191 | "html_url": "https://github.com/baxterthehacker", 192 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 193 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 194 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 195 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 196 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 197 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 198 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 199 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 200 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 201 | "type": "User", 202 | "site_admin": false 203 | }, 204 | "private": false, 205 | "html_url": "https://github.com/baxterthehacker/public-repo", 206 | "description": "", 207 | "fork": false, 208 | "url": "https://api.github.com/repos/baxterthehacker/public-repo", 209 | "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", 210 | "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", 211 | "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", 212 | "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", 213 | "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", 214 | "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", 215 | "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", 216 | "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", 217 | "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", 218 | "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", 219 | "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", 220 | "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", 221 | "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", 222 | "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", 223 | "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", 224 | "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", 225 | "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", 226 | "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", 227 | "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", 228 | "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", 229 | "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", 230 | "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", 231 | "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", 232 | "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", 233 | "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", 234 | "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", 235 | "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", 236 | "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", 237 | "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", 238 | "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", 239 | "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", 240 | "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", 241 | "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", 242 | "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", 243 | "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", 244 | "created_at": "2015-05-05T23:40:12Z", 245 | "updated_at": "2015-05-05T23:40:12Z", 246 | "pushed_at": "2015-05-05T23:40:26Z", 247 | "git_url": "git://github.com/baxterthehacker/public-repo.git", 248 | "ssh_url": "git@github.com:baxterthehacker/public-repo.git", 249 | "clone_url": "https://github.com/baxterthehacker/public-repo.git", 250 | "svn_url": "https://github.com/baxterthehacker/public-repo", 251 | "homepage": null, 252 | "size": 0, 253 | "stargazers_count": 0, 254 | "watchers_count": 0, 255 | "language": null, 256 | "has_issues": true, 257 | "has_downloads": true, 258 | "has_wiki": true, 259 | "has_pages": true, 260 | "forks_count": 0, 261 | "mirror_url": null, 262 | "open_issues_count": 1, 263 | "forks": 0, 264 | "open_issues": 1, 265 | "watchers": 0, 266 | "default_branch": "master" 267 | } 268 | }, 269 | "_links": { 270 | "self": { 271 | "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1" 272 | }, 273 | "html": { 274 | "href": "https://github.com/baxterthehacker/public-repo/pull/1" 275 | }, 276 | "issue": { 277 | "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1" 278 | }, 279 | "comments": { 280 | "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments" 281 | }, 282 | "review_comments": { 283 | "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments" 284 | }, 285 | "review_comment": { 286 | "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}" 287 | }, 288 | "commits": { 289 | "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits" 290 | }, 291 | "statuses": { 292 | "href": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c" 293 | } 294 | }, 295 | "merged": false, 296 | "mergeable": null, 297 | "mergeable_state": "unknown", 298 | "merged_by": null, 299 | "comments": 0, 300 | "review_comments": 0, 301 | "commits": 1, 302 | "additions": 1, 303 | "deletions": 1, 304 | "changed_files": 1 305 | }, 306 | "repository": { 307 | "id": 35129377, 308 | "name": "public-repo", 309 | "full_name": "baxterthehacker/public-repo", 310 | "owner": { 311 | "login": "baxterthehacker", 312 | "id": 6752317, 313 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 314 | "gravatar_id": "", 315 | "url": "https://api.github.com/users/baxterthehacker", 316 | "html_url": "https://github.com/baxterthehacker", 317 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 318 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 319 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 320 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 321 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 322 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 323 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 324 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 325 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 326 | "type": "User", 327 | "site_admin": false 328 | }, 329 | "private": false, 330 | "html_url": "https://github.com/baxterthehacker/public-repo", 331 | "description": "", 332 | "fork": false, 333 | "url": "https://api.github.com/repos/baxterthehacker/public-repo", 334 | "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", 335 | "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", 336 | "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", 337 | "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", 338 | "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", 339 | "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", 340 | "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", 341 | "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", 342 | "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", 343 | "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", 344 | "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", 345 | "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", 346 | "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", 347 | "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", 348 | "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", 349 | "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", 350 | "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", 351 | "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", 352 | "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", 353 | "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", 354 | "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", 355 | "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", 356 | "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", 357 | "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", 358 | "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", 359 | "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", 360 | "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", 361 | "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", 362 | "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", 363 | "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", 364 | "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", 365 | "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", 366 | "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", 367 | "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", 368 | "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", 369 | "created_at": "2015-05-05T23:40:12Z", 370 | "updated_at": "2015-05-05T23:40:12Z", 371 | "pushed_at": "2015-05-05T23:40:26Z", 372 | "git_url": "git://github.com/baxterthehacker/public-repo.git", 373 | "ssh_url": "git@github.com:baxterthehacker/public-repo.git", 374 | "clone_url": "https://github.com/baxterthehacker/public-repo.git", 375 | "svn_url": "https://github.com/baxterthehacker/public-repo", 376 | "homepage": null, 377 | "size": 0, 378 | "stargazers_count": 0, 379 | "watchers_count": 0, 380 | "language": null, 381 | "has_issues": true, 382 | "has_downloads": true, 383 | "has_wiki": true, 384 | "has_pages": true, 385 | "forks_count": 0, 386 | "mirror_url": null, 387 | "open_issues_count": 1, 388 | "forks": 0, 389 | "open_issues": 1, 390 | "watchers": 0, 391 | "default_branch": "master" 392 | }, 393 | "sender": { 394 | "login": "baxterthehacker", 395 | "id": 6752317, 396 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 397 | "gravatar_id": "", 398 | "url": "https://api.github.com/users/baxterthehacker", 399 | "html_url": "https://github.com/baxterthehacker", 400 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 401 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 402 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 403 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 404 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 405 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 406 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 407 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 408 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 409 | "type": "User", 410 | "site_admin": false 411 | } 412 | } 413 | -------------------------------------------------------------------------------- /tests/Provider/_files/github/push.json: -------------------------------------------------------------------------------- 1 | { 2 | "ref": "refs/heads/changes", 3 | "before": "9049f1265b7d61be4a8904a9a27120d2064dab3b", 4 | "after": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 5 | "created": false, 6 | "deleted": false, 7 | "forced": false, 8 | "base_ref": null, 9 | "compare": "https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f", 10 | "commits": [ 11 | { 12 | "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 13 | "distinct": true, 14 | "message": "Update README.md", 15 | "timestamp": "2015-05-05T19:40:15-04:00", 16 | "url": "https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 17 | "author": { 18 | "name": "baxterthehacker", 19 | "email": "baxterthehacker@users.noreply.github.com", 20 | "username": "baxterthehacker" 21 | }, 22 | "committer": { 23 | "name": "baxterthehacker", 24 | "email": "baxterthehacker@users.noreply.github.com", 25 | "username": "baxterthehacker" 26 | }, 27 | "added": [ 28 | ], 29 | "removed": [ 30 | ], 31 | "modified": [ 32 | "README.md" 33 | ] 34 | } 35 | ], 36 | "head_commit": { 37 | "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 38 | "distinct": true, 39 | "message": "Update README.md", 40 | "timestamp": "2015-05-05T19:40:15-04:00", 41 | "url": "https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 42 | "author": { 43 | "name": "baxterthehacker", 44 | "email": "baxterthehacker@users.noreply.github.com", 45 | "username": "baxterthehacker" 46 | }, 47 | "committer": { 48 | "name": "baxterthehacker", 49 | "email": "baxterthehacker@users.noreply.github.com", 50 | "username": "baxterthehacker" 51 | }, 52 | "added": [ 53 | ], 54 | "removed": [ 55 | ], 56 | "modified": [ 57 | "README.md" 58 | ] 59 | }, 60 | "repository": { 61 | "id": 35129377, 62 | "name": "public-repo", 63 | "full_name": "baxterthehacker/public-repo", 64 | "owner": { 65 | "name": "baxterthehacker", 66 | "email": "baxterthehacker@users.noreply.github.com" 67 | }, 68 | "private": false, 69 | "html_url": "https://github.com/baxterthehacker/public-repo", 70 | "description": "", 71 | "fork": false, 72 | "url": "https://github.com/baxterthehacker/public-repo", 73 | "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", 74 | "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", 75 | "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", 76 | "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", 77 | "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", 78 | "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", 79 | "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", 80 | "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", 81 | "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", 82 | "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", 83 | "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", 84 | "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", 85 | "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", 86 | "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", 87 | "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", 88 | "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", 89 | "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", 90 | "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", 91 | "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", 92 | "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", 93 | "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", 94 | "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", 95 | "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", 96 | "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", 97 | "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", 98 | "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", 99 | "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", 100 | "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", 101 | "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", 102 | "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", 103 | "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", 104 | "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", 105 | "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", 106 | "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", 107 | "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", 108 | "created_at": 1430869212, 109 | "updated_at": "2015-05-05T23:40:12Z", 110 | "pushed_at": 1430869217, 111 | "git_url": "git://github.com/baxterthehacker/public-repo.git", 112 | "ssh_url": "git@github.com:baxterthehacker/public-repo.git", 113 | "clone_url": "https://github.com/baxterthehacker/public-repo.git", 114 | "svn_url": "https://github.com/baxterthehacker/public-repo", 115 | "homepage": null, 116 | "size": 0, 117 | "stargazers_count": 0, 118 | "watchers_count": 0, 119 | "language": null, 120 | "has_issues": true, 121 | "has_downloads": true, 122 | "has_wiki": true, 123 | "has_pages": true, 124 | "forks_count": 0, 125 | "mirror_url": null, 126 | "open_issues_count": 0, 127 | "forks": 0, 128 | "open_issues": 0, 129 | "watchers": 0, 130 | "default_branch": "master", 131 | "stargazers": 0, 132 | "master_branch": "master" 133 | }, 134 | "pusher": { 135 | "name": "baxterthehacker", 136 | "email": "baxterthehacker@users.noreply.github.com" 137 | }, 138 | "sender": { 139 | "login": "baxterthehacker", 140 | "id": 6752317, 141 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 142 | "gravatar_id": "", 143 | "url": "https://api.github.com/users/baxterthehacker", 144 | "html_url": "https://github.com/baxterthehacker", 145 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 146 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 147 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 148 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 149 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 150 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 151 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 152 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 153 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 154 | "type": "User", 155 | "site_admin": false 156 | } 157 | } -------------------------------------------------------------------------------- /tests/Provider/_files/github/tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "ref": "refs/tags/test-tag", 3 | "before": "9049f1265b7d61be4a8904a9a27120d2064dab3b", 4 | "after": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 5 | "created": false, 6 | "deleted": false, 7 | "forced": false, 8 | "base_ref": null, 9 | "compare": "https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f", 10 | "commits": [ 11 | { 12 | "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 13 | "distinct": true, 14 | "message": "Update README.md", 15 | "timestamp": "2015-05-05T19:40:15-04:00", 16 | "url": "https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 17 | "author": { 18 | "name": "baxterthehacker", 19 | "email": "baxterthehacker@users.noreply.github.com", 20 | "username": "baxterthehacker" 21 | }, 22 | "committer": { 23 | "name": "baxterthehacker", 24 | "email": "baxterthehacker@users.noreply.github.com", 25 | "username": "baxterthehacker" 26 | }, 27 | "added": [ 28 | ], 29 | "removed": [ 30 | ], 31 | "modified": [ 32 | "README.md" 33 | ] 34 | } 35 | ], 36 | "head_commit": { 37 | "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 38 | "distinct": true, 39 | "message": "Update README.md", 40 | "timestamp": "2015-05-05T19:40:15-04:00", 41 | "url": "https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", 42 | "author": { 43 | "name": "baxterthehacker", 44 | "email": "baxterthehacker@users.noreply.github.com", 45 | "username": "baxterthehacker" 46 | }, 47 | "committer": { 48 | "name": "baxterthehacker", 49 | "email": "baxterthehacker@users.noreply.github.com", 50 | "username": "baxterthehacker" 51 | }, 52 | "added": [ 53 | ], 54 | "removed": [ 55 | ], 56 | "modified": [ 57 | "README.md" 58 | ] 59 | }, 60 | "repository": { 61 | "id": 35129377, 62 | "name": "public-repo", 63 | "full_name": "baxterthehacker/public-repo", 64 | "owner": { 65 | "name": "baxterthehacker", 66 | "email": "baxterthehacker@users.noreply.github.com" 67 | }, 68 | "private": false, 69 | "html_url": "https://github.com/baxterthehacker/public-repo", 70 | "description": "", 71 | "fork": false, 72 | "url": "https://github.com/baxterthehacker/public-repo", 73 | "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", 74 | "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", 75 | "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", 76 | "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", 77 | "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", 78 | "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", 79 | "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", 80 | "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", 81 | "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", 82 | "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", 83 | "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", 84 | "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", 85 | "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", 86 | "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", 87 | "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", 88 | "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", 89 | "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", 90 | "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", 91 | "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", 92 | "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", 93 | "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", 94 | "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", 95 | "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", 96 | "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", 97 | "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", 98 | "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", 99 | "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", 100 | "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", 101 | "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", 102 | "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", 103 | "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", 104 | "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", 105 | "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", 106 | "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", 107 | "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", 108 | "created_at": 1430869212, 109 | "updated_at": "2015-05-05T23:40:12Z", 110 | "pushed_at": 1430869217, 111 | "git_url": "git://github.com/baxterthehacker/public-repo.git", 112 | "ssh_url": "git@github.com:baxterthehacker/public-repo.git", 113 | "clone_url": "https://github.com/baxterthehacker/public-repo.git", 114 | "svn_url": "https://github.com/baxterthehacker/public-repo", 115 | "homepage": null, 116 | "size": 0, 117 | "stargazers_count": 0, 118 | "watchers_count": 0, 119 | "language": null, 120 | "has_issues": true, 121 | "has_downloads": true, 122 | "has_wiki": true, 123 | "has_pages": true, 124 | "forks_count": 0, 125 | "mirror_url": null, 126 | "open_issues_count": 0, 127 | "forks": 0, 128 | "open_issues": 0, 129 | "watchers": 0, 130 | "default_branch": "master", 131 | "stargazers": 0, 132 | "master_branch": "master" 133 | }, 134 | "pusher": { 135 | "name": "baxterthehacker", 136 | "email": "baxterthehacker@users.noreply.github.com" 137 | }, 138 | "sender": { 139 | "login": "baxterthehacker", 140 | "id": 6752317, 141 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", 142 | "gravatar_id": "", 143 | "url": "https://api.github.com/users/baxterthehacker", 144 | "html_url": "https://github.com/baxterthehacker", 145 | "followers_url": "https://api.github.com/users/baxterthehacker/followers", 146 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", 147 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", 148 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", 149 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", 150 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", 151 | "repos_url": "https://api.github.com/users/baxterthehacker/repos", 152 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", 153 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", 154 | "type": "User", 155 | "site_admin": false 156 | } 157 | } -------------------------------------------------------------------------------- /tests/Provider/_files/gitlab/issue.json: -------------------------------------------------------------------------------- 1 | { 2 | "object_kind": "issue", 3 | "user": { 4 | "name": "Administrator", 5 | "username": "root", 6 | "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" 7 | }, 8 | "project":{ 9 | "name":"Gitlab Test", 10 | "description":"Aut reprehenderit ut est.", 11 | "web_url":"http://example.com/gitlabhq/gitlab-test", 12 | "avatar_url":null, 13 | "git_ssh_url":"git@example.com:gitlabhq/gitlab-test.git", 14 | "git_http_url":"http://example.com/gitlabhq/gitlab-test.git", 15 | "namespace":"GitlabHQ", 16 | "visibility_level":20, 17 | "path_with_namespace":"gitlabhq/gitlab-test", 18 | "default_branch":"master", 19 | "homepage":"http://example.com/gitlabhq/gitlab-test", 20 | "url":"http://example.com/gitlabhq/gitlab-test.git", 21 | "ssh_url":"git@example.com:gitlabhq/gitlab-test.git", 22 | "http_url":"http://example.com/gitlabhq/gitlab-test.git" 23 | }, 24 | "repository":{ 25 | "name": "Gitlab Test", 26 | "url": "http://example.com/gitlabhq/gitlab-test.git", 27 | "description": "Aut reprehenderit ut est.", 28 | "homepage": "http://example.com/gitlabhq/gitlab-test" 29 | }, 30 | "object_attributes": { 31 | "id": 301, 32 | "title": "New API: create/update/delete file", 33 | "assignee_id": 51, 34 | "author_id": 51, 35 | "project_id": 14, 36 | "created_at": "2013-12-03T17:15:43Z", 37 | "updated_at": "2013-12-03T17:15:43Z", 38 | "position": 0, 39 | "branch_name": null, 40 | "description": "Create new API for manipulations with repository", 41 | "milestone_id": null, 42 | "state": "opened", 43 | "iid": 23, 44 | "url": "http://example.com/diaspora/issues/23", 45 | "action": "open" 46 | }, 47 | "assignee": { 48 | "name": "User1", 49 | "username": "user1", 50 | "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" 51 | } 52 | } -------------------------------------------------------------------------------- /tests/Provider/_files/gitlab/merge_request.json: -------------------------------------------------------------------------------- 1 | { 2 | "object_kind": "merge_request", 3 | "user": { 4 | "name": "Administrator", 5 | "username": "root", 6 | "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" 7 | }, 8 | "object_attributes": { 9 | "id": 99, 10 | "target_branch": "master", 11 | "source_branch": "ms-viewport", 12 | "source_project_id": 14, 13 | "author_id": 51, 14 | "assignee_id": 6, 15 | "title": "MS-Viewport", 16 | "created_at": "2013-12-03T17:23:34Z", 17 | "updated_at": "2013-12-03T17:23:34Z", 18 | "st_commits": null, 19 | "st_diffs": null, 20 | "milestone_id": null, 21 | "state": "opened", 22 | "merge_status": "unchecked", 23 | "target_project_id": 14, 24 | "iid": 1, 25 | "description": "", 26 | "source":{ 27 | "name":"Awesome Project", 28 | "description":"Aut reprehenderit ut est.", 29 | "web_url":"http://example.com/awesome_space/awesome_project", 30 | "avatar_url":null, 31 | "git_ssh_url":"git@example.com:awesome_space/awesome_project.git", 32 | "git_http_url":"http://example.com/awesome_space/awesome_project.git", 33 | "namespace":"Awesome Space", 34 | "visibility_level":20, 35 | "path_with_namespace":"awesome_space/awesome_project", 36 | "default_branch":"master", 37 | "homepage":"http://example.com/awesome_space/awesome_project", 38 | "url":"http://example.com/awesome_space/awesome_project.git", 39 | "ssh_url":"git@example.com:awesome_space/awesome_project.git", 40 | "http_url":"http://example.com/awesome_space/awesome_project.git" 41 | }, 42 | "target": { 43 | "name":"Awesome Project", 44 | "description":"Aut reprehenderit ut est.", 45 | "web_url":"http://example.com/awesome_space/awesome_project", 46 | "avatar_url":null, 47 | "git_ssh_url":"git@example.com:awesome_space/awesome_project.git", 48 | "git_http_url":"http://example.com/awesome_space/awesome_project.git", 49 | "namespace":"Awesome Space", 50 | "visibility_level":20, 51 | "path_with_namespace":"awesome_space/awesome_project", 52 | "default_branch":"master", 53 | "homepage":"http://example.com/awesome_space/awesome_project", 54 | "url":"http://example.com/awesome_space/awesome_project.git", 55 | "ssh_url":"git@example.com:awesome_space/awesome_project.git", 56 | "http_url":"http://example.com/awesome_space/awesome_project.git" 57 | }, 58 | "last_commit": { 59 | "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", 60 | "message": "fixed readme", 61 | "timestamp": "2012-01-03T23:36:29+02:00", 62 | "url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", 63 | "author": { 64 | "name": "GitLab dev user", 65 | "email": "gitlabdev@dv6700.(none)" 66 | } 67 | }, 68 | "work_in_progress": false, 69 | "url": "http://example.com/diaspora/merge_requests/1", 70 | "action": "open", 71 | "assignee": { 72 | "name": "User1", 73 | "username": "user1", 74 | "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /tests/Provider/_files/gitlab/push.json: -------------------------------------------------------------------------------- 1 | { 2 | "object_kind": "push", 3 | "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", 4 | "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", 5 | "ref": "refs/heads/master", 6 | "user_id": 4, 7 | "user_name": "John Smith", 8 | "user_email": "john@example.com", 9 | "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80", 10 | "project_id": 15, 11 | "project":{ 12 | "name":"Diaspora", 13 | "description":"", 14 | "web_url":"http://example.com/mike/diaspora", 15 | "avatar_url":null, 16 | "git_ssh_url":"git@example.com:mike/diaspora.git", 17 | "git_http_url":"http://example.com/mike/diaspora.git", 18 | "namespace":"Mike", 19 | "visibility_level":0, 20 | "path_with_namespace":"mike/diaspora", 21 | "default_branch":"master", 22 | "homepage":"http://example.com/mike/diaspora", 23 | "url":"git@example.com:mike/diasporadiaspora.git", 24 | "ssh_url":"git@example.com:mike/diaspora.git", 25 | "http_url":"http://example.com/mike/diaspora.git" 26 | }, 27 | "repository":{ 28 | "name": "Diaspora", 29 | "url": "git@example.com:mike/diasporadiaspora.git", 30 | "description": "", 31 | "homepage": "http://example.com/mike/diaspora", 32 | "git_http_url":"http://example.com/mike/diaspora.git", 33 | "git_ssh_url":"git@example.com:mike/diaspora.git", 34 | "visibility_level":0 35 | }, 36 | "commits": [ 37 | { 38 | "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", 39 | "message": "Update Catalan translation to e38cb41.", 40 | "timestamp": "2011-12-12T14:27:31+02:00", 41 | "url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", 42 | "author": { 43 | "name": "Jordi Mallach", 44 | "email": "jordi@softcatala.org" 45 | }, 46 | "added": ["CHANGELOG"], 47 | "modified": ["app/controller/application.rb"], 48 | "removed": [] 49 | }, 50 | { 51 | "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", 52 | "message": "fixed readme", 53 | "timestamp": "2012-01-03T23:36:29+02:00", 54 | "url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", 55 | "author": { 56 | "name": "GitLab dev user", 57 | "email": "gitlabdev@dv6700.(none)" 58 | }, 59 | "added": ["CHANGELOG"], 60 | "modified": ["app/controller/application.rb"], 61 | "removed": [] 62 | } 63 | ], 64 | "total_commits_count": 4 65 | } -------------------------------------------------------------------------------- /tests/Provider/_files/gitlab/tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "object_kind": "tag_push", 3 | "ref": "refs/tags/v1.0.0", 4 | "before": "0000000000000000000000000000000000000000", 5 | "after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", 6 | "user_id": 1, 7 | "user_name": "John Smith", 8 | "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80", 9 | "project_id": 1, 10 | "project":{ 11 | "name":"Example", 12 | "description":"", 13 | "web_url":"http://example.com/jsmith/example", 14 | "avatar_url":null, 15 | "git_ssh_url":"git@example.com:jsmith/example.git", 16 | "git_http_url":"http://example.com/jsmith/example.git", 17 | "namespace":"Jsmith", 18 | "visibility_level":0, 19 | "path_with_namespace":"jsmith/example", 20 | "default_branch":"master", 21 | "homepage":"http://example.com/jsmith/example", 22 | "url":"git@example.com:jsmith/example.git", 23 | "ssh_url":"git@example.com:jsmith/example.git", 24 | "http_url":"http://example.com/jsmith/example.git" 25 | }, 26 | "repository":{ 27 | "name": "jsmith", 28 | "url": "ssh://git@example.com/jsmith/example.git", 29 | "description": "", 30 | "homepage": "http://example.com/jsmith/example", 31 | "git_http_url":"http://example.com/jsmith/example.git", 32 | "git_ssh_url":"git@example.com:jsmith/example.git", 33 | "visibility_level":0 34 | }, 35 | "commits": [], 36 | "total_commits_count": 0 37 | } -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 |