diff --git a/app/Utils/RepositoryUtils.php b/app/Utils/RepositoryUtils.php index b18f0cc098..0caad6fb5a 100644 --- a/app/Utils/RepositoryUtils.php +++ b/app/Utils/RepositoryUtils.php @@ -10,10 +10,31 @@ use CDash\Model\Project; use CDash\ServiceContainer; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Str; +use Illuminate\Support\Uri; use PDO; class RepositoryUtils { + public static function getEnterpriseUrl(): ?string + { + $url = config('cdash.github_enterprise_url'); + return is_string($url) && $url !== '' ? $url : null; + } + + public static function isGitHubUrl(string $url): bool + { + if (str_contains($url, 'github.com')) { + return true; + } + $enterpriseUrl = self::getEnterpriseUrl(); + if ($enterpriseUrl !== null) { + $host = Uri::of($enterpriseUrl)->host(); + return is_string($host) && str_contains($url, $host); + } + return false; + } + /** Return the GitHub diff URL */ public static function get_github_diff_url($projecturl, $directory, $file, $revision) { @@ -143,22 +164,21 @@ public static function post_pull_request_comment($projectid, $pull_request, $com } } - /** Convert GitHub repository viewer URL into corresponding API URL. */ - public static function get_github_api_url($github_url): string + /** + * Convert a GitHub repository viewer URL (e.g. https:////) + * into the corresponding REST API URL. + */ + public static function get_github_api_url(string $github_url): string { - /* - * For a URL of the form: - * ...://github.com// - * We return: - * ...://api.github.com/repos// - */ - $idx1 = strpos($github_url, 'github.com'); - $idx2 = $idx1 + strlen('github.com/'); - $api_url = substr($github_url, 0, $idx2); - $api_url = str_replace('github.com', 'api.github.com', $api_url); - $api_url .= 'repos/'; - $api_url .= substr($github_url, $idx2); - return $api_url; + $enterpriseUrl = self::getEnterpriseUrl(); + $host = $enterpriseUrl !== null ? Uri::of($enterpriseUrl)->host() : null; + + if (is_string($host) && str_contains($github_url, $host)) { + // GHE uses /api/v3/repos/ as the API base + return Str::replaceFirst($host . '/', $host . '/api/v3/repos/', $github_url); + } + // GitHub.com uses api.github.com/repos/ as the API base + return Str::replaceFirst('github.com/', 'api.github.com/repos/', $github_url); } public static function post_github_pull_request_comment(Project $project, $pull_request, $comment, $cdash_url): void @@ -166,7 +186,7 @@ public static function post_github_pull_request_comment(Project $project, $pull_ $repo = null; $repositories = $project->GetRepositories(); foreach ($repositories as $repository) { - if (str_contains($repository['url'], 'github.com')) { + if (self::isGitHubUrl($repository['url'])) { $repo = $repository; break; } diff --git a/app/cdash/app/Lib/Repository/GitHub.php b/app/cdash/app/Lib/Repository/GitHub.php index 32383b1374..644d5db5e9 100644 --- a/app/cdash/app/Lib/Repository/GitHub.php +++ b/app/cdash/app/Lib/Repository/GitHub.php @@ -19,6 +19,7 @@ use App\Models\BuildUpdateFile; use App\Models\PendingSubmissions; +use App\Utils\RepositoryUtils; use CDash\Database; use CDash\Model\Build; use CDash\Model\BuildUpdate; @@ -76,7 +77,7 @@ public function __construct(Project $project) $repositories = $this->project->GetRepositories(); foreach ($repositories as $repo) { - if (str_contains($repo['url'], 'github.com')) { + if (RepositoryUtils::isGitHubUrl($repo['url'])) { $this->installationId = $repo['username']; break; } @@ -93,7 +94,8 @@ public function setApiClient(GitHubClient $client): void protected function initializeApiClient(): void { $builder = new GitHubBuilder(); - $apiClient = new GitHubClient($builder, 'machine-man-preview'); + $enterpriseUrl = RepositoryUtils::getEnterpriseUrl(); + $apiClient = new GitHubClient($builder, null, $enterpriseUrl); $this->setApiClient($apiClient); } diff --git a/config/cdash.php b/config/cdash.php index 670da91ac7..018976e531 100755 --- a/config/cdash.php +++ b/config/cdash.php @@ -39,6 +39,7 @@ 'delete_old_subprojects' => env('DELETE_OLD_SUBPROJECTS', true), 'github_always_pass' => env('GITHUB_ALWAYS_PASS', false), 'github_app_id' => env('GITHUB_APP_ID', null), + 'github_enterprise_url' => env('GITHUB_ENTERPRISE_URL', null), 'github_private_key' => env('GITHUB_PRIVATE_KEY', null), 'github_webhook_secret' => env('GITHUB_WEBHOOK_SECRET', null), 'large_text_limit' => env('LARGE_TEXT_LIMIT', 0), diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 8f26dd0f91..629adc160b 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5436,12 +5436,6 @@ parameters: count: 1 path: app/Utils/RepositoryUtils.php - - - rawMessage: 'Method App\Utils\RepositoryUtils::get_github_api_url() has parameter $github_url with no type specified.' - identifier: missingType.parameter - count: 1 - path: app/Utils/RepositoryUtils.php - - rawMessage: 'Method App\Utils\RepositoryUtils::get_github_diff_url() has no return type specified.' identifier: missingType.return @@ -5628,12 +5622,6 @@ parameters: count: 1 path: app/Utils/RepositoryUtils.php - - - rawMessage: 'Only numeric types are allowed in +, int<0, max>|false given on the left side.' - identifier: plus.leftNonNumeric - count: 1 - path: app/Utils/RepositoryUtils.php - - rawMessage: 'Only numeric types are allowed in +, int|false given on the left side.' identifier: plus.leftNonNumeric