fix(previews): restrict PR loading and status updates to GitHub Apps

Add Application::isGithubAppSource(), which checks that the source is a
GithubApp, and use it in place of is_github_based() for pull request
status updates in ApplicationDeploymentJob and for the "Load pull
requests" action in the previews view.

Previews::load_prs now throws an error for non-GitHub App sources
instead of calling the GitHub API with a GitLab or other source. Also
adds a test checking that GitLab sources don't show or load GitHub pull
requests.
This commit is contained in:
Andras Bacsai
2026-10-04 12:29:48 +02:00
parent 9f7697d501
commit 4c2253c2ad
5 changed files with 30 additions and 4 deletions
+3 -3
View File
@@ -294,7 +294,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$this->preview->generate_preview_fqdn();
}
}
if ($this->application->is_github_based()) {
if ($this->application->isGithubAppSource()) {
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::IN_PROGRESS);
}
if ($this->application->build_pack === 'dockerfile') {
@@ -384,7 +384,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$this->detectBuildKitCapabilities();
$this->decide_what_to_do();
} catch (Exception $e) {
if ($this->pull_request_id !== 0 && $this->application->is_github_based()) {
if ($this->pull_request_id !== 0 && $this->application->isGithubAppSource()) {
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::ERROR);
}
$this->fail($e);
@@ -605,7 +605,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
}
if ($this->pull_request_id !== 0) {
if ($this->application->is_github_based()) {
if ($this->application->isGithubAppSource()) {
try {
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::FINISHED);
} catch (Exception $e) {
@@ -94,6 +94,9 @@ class Previews extends Component
{
try {
$this->authorize('update', $this->application);
if (! $this->application->isGithubAppSource()) {
throw new \Exception('Loading pull requests is only supported for GitHub App sources.');
}
['rate_limit_remaining' => $rate_limit_remaining, 'data' => $data] = githubApi(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/pulls");
$this->rate_limit_remaining = $rate_limit_remaining;
$this->pull_requests = $data->sortBy('number')->values();
+5
View File
@@ -652,6 +652,11 @@ class Application extends BaseModel
return false;
}
public function isGithubAppSource(): bool
{
return $this->source instanceof GithubApp;
}
public function isForceHttpsEnabled()
{
return data_get($this, 'settings.is_force_https_enabled', false);
@@ -7,7 +7,7 @@
helper="Automatic pull request deployments and who can trigger them.">
<x-slot:actions>
@can('update', $application)
@if ($application->is_github_based())
@if ($application->isGithubAppSource())
<x-modal-input title="Pull requests"
subtitle="Load open pull requests from GitHub, then configure or deploy a preview."
:wireIgnore="false" :isLarge="true">
@@ -3,6 +3,7 @@
use App\Livewire\Project\Application\Previews;
use App\Models\Application;
use App\Models\Environment;
use App\Models\GitlabApp;
use App\Models\InstanceSettings;
use App\Models\PrivateKey;
use App\Models\Project;
@@ -117,6 +118,23 @@ it('renders preview deployment enablement as a section action', function () {
expect($this->application->fresh()->settings->is_preview_deployments_enabled)->toBeTrue();
});
it('does not load GitHub pull requests for GitLab sources', function () {
$gitlabApp = GitlabApp::create([
'name' => 'Self-hosted GitLab',
'api_url' => 'https://gitlab.example.com/api/v4',
'html_url' => 'https://gitlab.example.com',
'team_id' => $this->team->id,
]);
$this->application->update(['source_id' => $gitlabApp->id, 'source_type' => GitlabApp::class]);
Livewire::test(Previews::class, ['application' => $this->application->fresh()])
->assertSee('PR deployment access')
->assertDontSee('Load pull requests')
->call('load_prs')
->assertSet('rate_limit_remaining', 0)
->assertDispatched('error');
});
it('does not show git preview settings for non-git applications', function (string $buildPack, ?string $dockerfile) {
$this->application->update(['build_pack' => $buildPack, 'dockerfile' => $dockerfile]);