src/MultiTester/GitHub.php
created.
src/MultiTester/Project.php
changed.
1 | + | <?php |
|
2 | + | ||
3 | + | namespace MultiTester; |
|
4 | + | ||
5 | + | class GitHub |
|
6 | + | { |
|
7 | + | private $repo; |
|
8 | + | ||
9 | + | public function __construct(string $repo) |
|
10 | + | { |
|
11 | + | $this->repo = $repo; |
|
12 | + | } |
|
13 | + | ||
14 | + | private function getCurl(string $url): ?string |
|
15 | + | { |
|
16 | + | $token = getenv('GITHUB_TOKEN'); |
|
17 | + | ||
18 | + | return shell_exec('curl -s '. |
|
19 | + | '-H "Accept: application/vnd.github.antiope-preview+json" '. |
|
20 | + | (empty($token) ? '' : '-H "Authorization: token '.$token.'" '). |
|
21 | + | "https://api.github.com/repos/{$this->repo}/commits$url" |
|
22 | + | ); |
|
23 | + | } |
|
24 | + | ||
25 | + | private function getJSON(string $url) |
|
26 | + | { |
|
27 | + | return json_decode($this->getCurl($url), true); |
|
28 | + | } |
|
29 | + | ||
30 | + | private function isSuccessful(string $sha): bool |
|
31 | + | { |
|
32 | + | $data = $this->getJSON("/$sha/check-suites"); |
|
33 | + | $checks = array_filter($data['check_suites'], function ($status) { |
|
34 | + | return $status['status'] !== 'queued'; |
|
35 | + | }); |
|
36 | + | ||
37 | + | foreach ($checks as $check) { |
|
38 | + | if ($check['conclusion'] !== 'neutral' && $check['conclusion'] !== 'success') { |
|
39 | + | return false; |
|
40 | + | } |
|
41 | + | } |
|
42 | + | ||
43 | + | return true; |
|
44 | + | } |
|
45 | + | ||
46 | + | public function getFirstSuccessfulCommit(?string $branch = null, int $limit = 30): string |
|
47 | + | { |
|
48 | + | $commits = array_slice($this->getJSON(($branch ? "?sha=$branch" : '')), 0, $limit); |
|
49 | + | ||
50 | + | foreach ($commits as ['sha' => $sha]) { |
|
51 | + | if ($this->isSuccessful($sha)) { |
|
52 | + | return $sha; |
|
53 | + | } |
|
54 | + | } |
|
55 | + | ||
56 | + | $message = count($commits) . ' last commits'; |
|
57 | + | ||
58 | + | if ($branch) { |
|
59 | + | $message .= ' on ' . $branch; |
|
60 | + | } |
|
61 | + | ||
62 | + | throw new MultiTesterException("No successful commit found in the $message of {$this->repo}."); |
|
63 | + | } |
|
64 | + | } |
222 | 222 | $this->seedSourceSetting($settings); |
|
223 | 223 | $this->checkSourceSetting($settings); |
|
224 | 224 | $settings['clone'] = ['git clone ' . $settings['source']['url'] . ' .' . ($this->config->quiet ? ' --quiet' : '')]; |
|
225 | + | $reference = $settings['source']['reference'] ?? null; |
|
226 | + | $successOnly = $settings['source']['success_only'] ?? false; |
|
225 | 227 | ||
226 | - | if (isset($settings['source']['reference'])) { |
|
227 | - | $settings['clone'][] = 'git checkout ' . $settings['source']['reference'] . ($this->config->quiet ? ' --quiet' : ''); |
|
228 | + | if ($reference || $successOnly) { |
|
229 | + | if ($successOnly ?? false) { |
|
230 | + | if (!preg_match('/(?:https?:\/\/github\.com\/|git@github\.com:)([^\/]+\/[^\/]+)(?:\.git)?$/U', $settings['source']['url'], $match)) { |
|
231 | + | throw new MultiTesterException('success_only can be used only with github.com source URLs for now.'); |
|
232 | + | } |
|
233 | + | ||
234 | + | $gitHub = new GitHub($match[1]); |
|
235 | + | $reference = $gitHub->getFirstSuccessfulCommit($reference); |
|
236 | + | ||
237 | + | var_dump($reference); |
|
238 | + | exit; |
|
239 | + | } |
|
240 | + | ||
241 | + | $settings['clone'][] = 'git checkout ' . $reference . ($this->config->quiet ? ' --quiet' : ''); |
|
228 | 242 | } |
|
229 | 243 | } |
|
230 | 244 |
Files | Complexity | Coverage |
---|---|---|
src/MultiTester | 206 | 93.29% |
Project Totals (13 files) | 206 | 93.29% |
7.3=.3 TRAVIS_OS_NAME=linux
7.1=.1 TRAVIS_OS_NAME=linux
TRAVIS_OS_NAME=linux 7.4=.4
7.2=.2 TRAVIS_OS_NAME=linux