Skip to content

Commit c936b17

Browse files
Add GitHub Enterprise support (#3720)
Add support for GitHub Enterprise Server (GHE) so CDash can post check runs and commit statuses to self-hosted GHE instances - `GITHUB_ENTERPRISE_URL`, when set, will have CDash target that instance for GitHub API interactions --------- Co-authored-by: William Allen <william.allen@kitware.com>
1 parent 0e2539a commit c936b17

4 files changed

Lines changed: 41 additions & 30 deletions

File tree

app/Utils/RepositoryUtils.php

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,31 @@
1010
use CDash\Model\Project;
1111
use CDash\ServiceContainer;
1212
use Illuminate\Support\Facades\Log;
13+
use Illuminate\Support\Str;
14+
use Illuminate\Support\Uri;
1315
use PDO;
1416

1517
class RepositoryUtils
1618
{
19+
public static function getEnterpriseUrl(): ?string
20+
{
21+
$url = config('cdash.github_enterprise_url');
22+
return is_string($url) && $url !== '' ? $url : null;
23+
}
24+
25+
public static function isGitHubUrl(string $url): bool
26+
{
27+
if (str_contains($url, 'github.com')) {
28+
return true;
29+
}
30+
$enterpriseUrl = self::getEnterpriseUrl();
31+
if ($enterpriseUrl !== null) {
32+
$host = Uri::of($enterpriseUrl)->host();
33+
return is_string($host) && str_contains($url, $host);
34+
}
35+
return false;
36+
}
37+
1738
/** Return the GitHub diff URL */
1839
public static function get_github_diff_url($projecturl, $directory, $file, $revision)
1940
{
@@ -143,30 +164,29 @@ public static function post_pull_request_comment($projectid, $pull_request, $com
143164
}
144165
}
145166

146-
/** Convert GitHub repository viewer URL into corresponding API URL. */
147-
public static function get_github_api_url($github_url): string
167+
/**
168+
* Convert a GitHub repository viewer URL (e.g. https://<host>/<user>/<repo>)
169+
* into the corresponding REST API URL.
170+
*/
171+
public static function get_github_api_url(string $github_url): string
148172
{
149-
/*
150-
* For a URL of the form:
151-
* ...://github.com/<user>/<repo>
152-
* We return:
153-
* ...://api.github.com/repos/<user>/<repo>
154-
*/
155-
$idx1 = strpos($github_url, 'github.com');
156-
$idx2 = $idx1 + strlen('github.com/');
157-
$api_url = substr($github_url, 0, $idx2);
158-
$api_url = str_replace('github.com', 'api.github.com', $api_url);
159-
$api_url .= 'repos/';
160-
$api_url .= substr($github_url, $idx2);
161-
return $api_url;
173+
$enterpriseUrl = self::getEnterpriseUrl();
174+
$host = $enterpriseUrl !== null ? Uri::of($enterpriseUrl)->host() : null;
175+
176+
if (is_string($host) && str_contains($github_url, $host)) {
177+
// GHE uses <host>/api/v3/repos/ as the API base
178+
return Str::replaceFirst($host . '/', $host . '/api/v3/repos/', $github_url);
179+
}
180+
// GitHub.com uses api.github.com/repos/ as the API base
181+
return Str::replaceFirst('github.com/', 'api.github.com/repos/', $github_url);
162182
}
163183

164184
public static function post_github_pull_request_comment(Project $project, $pull_request, $comment, $cdash_url): void
165185
{
166186
$repo = null;
167187
$repositories = $project->GetRepositories();
168188
foreach ($repositories as $repository) {
169-
if (str_contains($repository['url'], 'github.com')) {
189+
if (self::isGitHubUrl($repository['url'])) {
170190
$repo = $repository;
171191
break;
172192
}

app/cdash/app/Lib/Repository/GitHub.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use App\Models\BuildUpdateFile;
2121
use App\Models\PendingSubmissions;
22+
use App\Utils\RepositoryUtils;
2223
use CDash\Database;
2324
use CDash\Model\Build;
2425
use CDash\Model\BuildUpdate;
@@ -76,7 +77,7 @@ public function __construct(Project $project)
7677

7778
$repositories = $this->project->GetRepositories();
7879
foreach ($repositories as $repo) {
79-
if (str_contains($repo['url'], 'github.com')) {
80+
if (RepositoryUtils::isGitHubUrl($repo['url'])) {
8081
$this->installationId = $repo['username'];
8182
break;
8283
}
@@ -93,7 +94,8 @@ public function setApiClient(GitHubClient $client): void
9394
protected function initializeApiClient(): void
9495
{
9596
$builder = new GitHubBuilder();
96-
$apiClient = new GitHubClient($builder, 'machine-man-preview');
97+
$enterpriseUrl = RepositoryUtils::getEnterpriseUrl();
98+
$apiClient = new GitHubClient($builder, null, $enterpriseUrl);
9799
$this->setApiClient($apiClient);
98100
}
99101

config/cdash.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
'delete_old_subprojects' => env('DELETE_OLD_SUBPROJECTS', true),
4040
'github_always_pass' => env('GITHUB_ALWAYS_PASS', false),
4141
'github_app_id' => env('GITHUB_APP_ID', null),
42+
'github_enterprise_url' => env('GITHUB_ENTERPRISE_URL', null),
4243
'github_private_key' => env('GITHUB_PRIVATE_KEY', null),
4344
'github_webhook_secret' => env('GITHUB_WEBHOOK_SECRET', null),
4445
'large_text_limit' => env('LARGE_TEXT_LIMIT', 0),

phpstan-baseline.neon

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5436,12 +5436,6 @@ parameters:
54365436
count: 1
54375437
path: app/Utils/RepositoryUtils.php
54385438

5439-
-
5440-
rawMessage: 'Method App\Utils\RepositoryUtils::get_github_api_url() has parameter $github_url with no type specified.'
5441-
identifier: missingType.parameter
5442-
count: 1
5443-
path: app/Utils/RepositoryUtils.php
5444-
54455439
-
54465440
rawMessage: 'Method App\Utils\RepositoryUtils::get_github_diff_url() has no return type specified.'
54475441
identifier: missingType.return
@@ -5628,12 +5622,6 @@ parameters:
56285622
count: 1
56295623
path: app/Utils/RepositoryUtils.php
56305624

5631-
-
5632-
rawMessage: 'Only numeric types are allowed in +, int<0, max>|false given on the left side.'
5633-
identifier: plus.leftNonNumeric
5634-
count: 1
5635-
path: app/Utils/RepositoryUtils.php
5636-
56375625
-
56385626
rawMessage: 'Only numeric types are allowed in +, int|false given on the left side.'
56395627
identifier: plus.leftNonNumeric

0 commit comments

Comments
 (0)